UVa 10819 - Trouble of 13-Dots

题目:买东西,给你钱和物品的价值和满意值,求最大的满意值。(超过2000可以减少200)

分析:dp,01背包。当钱数超过1800时,总钱数+200即可。

           这里要注意题意,必须买了价格高于2000的物品才会打折,所以要判断总价格。

           可以用放满作为条件限制(除了F[0] = 0,其他都初始化负无穷,此时每个值都是取对应的准确价格);

           也可以一般背包(不超过容量),不过要进行放满检测(从后向前找和F[N]相同的值,最前面是满的);

           如果,这时的值不超过2000,则不打折。(如果之前m加了200,返回F[N-200])

说明:~scanf的~忘记写了,RE了几次才发现,o(╯□╰)o。

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>

using namespace std;

int F[10220];
int c[115],w[115];

int main()
{
	int m,n;
	while (~scanf("%d%d",&m,&n)) {
		for (int i = 1 ; i <= n ; ++ i)
			scanf("%d%d",&c[i],&w[i]);
		
		memset(F, 0, sizeof(F));
		if (m > 1800) m += 200;
		for (int i = 1 ; i <= n ; ++ i) 
			for (int j = m ; j >= c[i] ; -- j)
				if (F[j] < F[j-c[i]]+w[i])
					F[j] = F[j-c[i]]+w[i];
		
		int f = m;
		while (f > 0 && F[f] == F[f-1]) -- f;
		if (f <= 2000 && m > 2000)
			printf("%d\n",F[m-200]);
		else printf("%d\n",F[m]);
	}
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值