题目:买东西,给你钱和物品的价值和满意值,求最大的满意值。(超过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;
}