有n个重量价值分别为Wi,vi的物品,从这些物品中挑选总重量不超过W的物品,求所有挑选方案中价值总和的最大值
定义dp[i+1][j]=前i个物品中挑选出价值总和为j时总重量的最小值(不存在时就是一个充分大的数值INF),由于前0个物品中什么都挑选不了,所以dp[0][0]=0,dp[0][j]=INF.
此外,前i个物品中挑选出价值总和为j时,一定有
前i-1个物品中挑选价值总和为j的部分
前i-1物品中挑选价值总和为j-v【i】的部分,然后再选中第i个物品
void solve()
{
for(int i=0;i<n;i++)
{
for(int j=w;j>=w[i];j--)
{
dp[j]=max(dp[j],dp[j-w[i]+v[i]);
}
}
}
饭卡
电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
Input
多组数据。对于每组数据:
第一行为正整数n,表示菜的数量。n<=1000。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m,表示卡上的余额。m<=1000。
n=0表示数据结束。
Output
对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。
Sample Input
1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0
Sample Output
-45
32
题意:01背包问题的变种问题。既然卡可以在5元之前透支,那么首先,若余额在其之下,便可直接输出 ,其次我们应当选择最贵的饭菜在最后一次购买它。便可转化为一个 M-5空间的背包将其存到最满