320K |
188MS |
GCC |
778B |
2009-02-15 21:37:37 |
之前想用背包(搜索)做,一直做不出来,不知道是不是考虑的不全面。(wa)
后来用搜索全部解来找最小值来做,出现time limited
无奈,只好去网上寻求帮助:看了一个人对这道题的做法的一句话:
用a[i]表示重量为i的最小价值,对于每一个价值为v[j],重量为w[j]的硬币,用a[i]+v[j]去刷新a[i+w[j]]。
也就是说用动态规划来做了。。O(硬币的总类数*包总重量)
在pku的discuss上还发现有O(硬币的总类数*硬币的总类数的做法),实在无法参透。。
哎,我太菜了。。。
现把我写的代码附上:
Code
#include<stdio.h>
#include<stdlib.h>
struct coin{
int p;
int w;
};
struct coin a[502];
int t,weight,n,ans,flag,dp[10002];
void input()
{
int i;
scanf("%d %d",&i,&weight);
weight-=i;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d %d",&a[i].p,&a[i].w);
for(i=0;i<=weight;i++)
dp[i]=-1;
}
void process()
{
int i,j;
dp[0]=0;
for(i=1;i<=weight;i++){
for(j=0;j<n;j++){
if(i<a[j].w)
continue;
if(dp[i-a[j].w]!=-1&&(dp[i]==-1||dp[i-a[j].w]+a[j].p<dp[i]))
dp[i]=dp[i-a[j].w]+a[j].p;
}
}
if(dp[weight]==-1)
printf("This is impossible.\n");
else
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[weight]);
}
int main()
{
scanf("%d",&t);
while(t--){
input();
process();
}
return 0;
}