hdu2546: http://acm.hdu.edu.cn/showproblem.php?pid=2546
题意:输入n,表示有n种菜可购买,再输入n个数v[i],表示菜的价格,再输入m,表示卡上有m元,规定若卡上余额大于等于5则可购买任意价钱的物品(即使买后余额为负),否则不可购买任何物品,求最后卡上最小余额
解法:01背包+贪心:最贵的物品肯定要被购买到,所以先选出来最后购买。先对除了最贵的物品外其余物品进行01背包处理,总容量为m-5,物品费用和价值都为w[i]。
code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
int v[1010],w[1010],f[1010];
int maxx(int a,int b)
{
if(a>b)
return a;
else
return b;
}
int main()
{
int n,m,x,max;
while(1)
{
scanf("%d",&n);
if(n==0)break;
max=0;
for(int i=0;i<n;i++)
{
scanf("%d",&v[i]);
if(v[i]>max)
{
max=v[i];
x=i;
}
}
scanf("%d",&m);
if(m<5)
{
printf("%d\n",m);
continue;
}
int t=0;
for(int i=0;i<n;i++)
{
if(i==x)
continue;
w[t++]=v[i];
}
memset(f,0,sizeof(f));
for(int i=0;i<n-1;i++) //01背包
{
for(int j=m-5;j>=0;j--)
{
if(j>=w[i])
{
f[j]=maxx(f[j],f[j-w[i]]+w[i]);
}
}
}
m=m-f[m-5]-max;
printf("%d\n",m);
}
}
/*input:
1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0
output:
-45
32
*/