贪心模型

其实只是把复习题做了一遍。

1.硬币问题

有1 元、5 元、10 元、50 元、100 元、500 元硬币若干枚,现在要用这些硬币来支付A 元,求最少需要多少枚硬币?

#include <cstdio>
#include <iostream>

using namespace std;

int a;
int tot,now;
int coin[6] = {500,100,50,10,5,1};

int main()
{
	scanf("%d",&a);
	for(int i = 0; i <= 5; i++)
	{
		now = a / coin[i];
		tot += now;
		a -= now * coin[i];
		if(a == 0) break;
	}
	printf("%d",tot);
	return 0;
}
2.装载问题
n 个物品,第i 个物品重量为wi,选择尽量多的物品使得总重量不超过C
#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 1001;
int n,c;
int tot;
int w[maxn];

int main()
{
	scanf("%d%d",&n,&c);
	for(int i = 1; i <= n; i++)
		scanf("%d",&w[i]);
	sort(w+1, w+1+n);
	for(int i = 1; i <= n; i++)
		if(w[i] + tot <= c)tot += w[i];
		else break;
	printf("%d",tot);
	return 0;
}

3.部分背包问题
n 个物品,第i 个物品重量为wi,价值为vi. 求在总重量不超过C 的情况下选出物品的总价值最高是多少。物品可以只取一部分,价值重量按比例计算

#include <iostream>
#include <cstdio>
#include <algorithm>


using namespace std;

const int maxn = 1001;
int n,c;
int totw,totv;
struct data{
	int w,v;
	double s;
	bool operator < (const data &right)const{
		return s < right.s;
	}
};
data a[maxn];

int main()
{
	scanf("%d%d",&n,&c);
	for(int i = 1; i <= n; i++)
		scanf("%d%d",&a[i].w,&a[i].v),a[i].s = a[i].v / a[i].w;
	sort(a+1, a+1+n);
	for(int i = 1; i <= n; i++)
		if(a[i].w + totw <= c)
		{
			totw += a[i].w;
			totv += a[i].v;
		}
		else if(totw < c)
			{
				totv += a[i].v * (c - totw) / a[i].w;
			}
			else break;
	printf("%d",totv);
	return 0;
}
4.乘船问题
n 个人,第i 个人重量为wi,每艘船载重量均为Ci,最多乘两个人。求最少几艘船能载所有人
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 1001;
int n,c;
int tot,l;
int w[maxn];

int main()
{
	scanf("%d%d",&n,&c),l = n;
	for(int i = 1; i <= n; i++)
		scanf("%d",&w[i]);
	for(int i = 1; i <= l; i++)
		for(int j = l; j >= i; j--)
		{
			tot++;
			l--;
			if(w[i] + w[j]< c) break;
		}
	printf("%d",tot);
	return 0;
}
5.给定n 个区间,每个区间左右端点分别为li; ri,现在要求选出尽量多的区间使得它们两两不相交(不包括端点),问最多能选出几个区间
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 1001;
int n;
int tot,lst;
struct data{
	int r,l;
	bool operator < (const data &right)const{
		if(l == right.l) return r < right.r;
		return l < right.l;
	}
};
data a[maxn];

int main()
{
	scanf("%d",&n);
	for(int i = 1; i <= n; i++)
		scanf("%d%d",&a[i].r,&a[i].l);
	sort(a+1, a+1+n);
	for(int i = 1; i <= n; i++)
		if(a[i].r >= lst)
		{
			lst = a[i].l;
			tot++;
		}
	printf("%d",tot);
	return 0;
}

6.选点问题
给定n 个区间[li; ri],取尽量少的点使得所有区间内部至少一个点

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 1001;
int n;
int tot,lst;
struct data{
	int r,l;
	bool operator < (const data &right)const{
		return r < right.r || r == right.r && l > right.l;  
	}
};
data a[maxn];

int main()
{
	scanf("%d",&n);
	for(int i = 1; i <= n; i++)
		scanf("%d%d",&a[i].r,&a[i].l);
	sort(a+1, a+1+n);
	lst = -1;
	for(int i = 1; i <= n; i++)
		if(lst < a[i].r)
        {
        	lst = a[i].l;
            tot++;
        }
	printf("%d",tot);
	return 0;
}

6.顺序问题
给定n 数ai,再给出n 个数bi,现在要求你重新排列b 的顺序,使得

n
Σai bi 最小
i=1

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 1001;
int n;
int a[maxn],b[maxn];
int aa[maxn],bb[maxn],lst[maxn];

bool cmp(const int &x, const int &y){
	return x > y;
}

int main()
{
	scanf("%d",&n);
	for(int i = 1; i <= n; i++)
		scanf("%d%d",&a[i],&b[i]), aa[i] = a[i], bb[i] = b[i];
	sort(aa+1, aa+1+n);
	sort(bb+1, bb+1+n, cmp);
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= n; j++)
		{
			if(a[i] == aa[j]) a[i] = j;
			if(b[i] == bb[j]) b[i] = j;
		}
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= n; j++)
			if(a[i] == b[j]) lst[i] = bb[b[j]];
	for(int i = 1; i <= n; i++)
		printf("%d ",lst[i]);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值