POJ 3260(DP)

来源:互联网 发布:文化衫设计软件 编辑:程序博客网 时间:2024/05/17 22:17


题意是:农场主去买东西,给定买价值为T的物品,还有n种面值的硬币,及每种硬币的数量。而卖方也只能有那几种硬币,但是个数不限。

所以要把支付钱的组合分为俩个DP来求:

1):求卖方的找零应该用的是完全背包。

2):农场主的支付应该是变化版的0-1背包。

3):所以找到使用数量最小的钱数。minn=dp1[i]-dp2[i-t];

AC代码:

#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#define MAXX 999999999using namespace std;int dp1[10008],dp2[10008];int q[108],w[108];int main(){int n,i,j,t,sum,ant;while(~scanf("%d%d",&n,&t)){for(i=1;i<=n;i++) scanf("%d",&q[i]);for(i=1;i<=n;i++) scanf("%d",&w[i]);for(i=0;i<=10003;i++) dp1[i]=dp2[i]=MAXX;dp1[0]=dp2[0]=0;for(i=1;i<=n;i++){  //完全背包for(j=q[i];j <= 10000;j++)   dp1[j]=min(dp1[j],dp1[j-q[i]]+1);}for(i=1;i<=n;i++){for(j=q[i];j<=10000;j++){ant=w[i];for(int z=1;z<=ant && z*q[i] <=j;z=z*2){  //0-1背包。ant-=z;dp2[j]=min(dp2[j],dp2[j-z*q[i]]+z);}if(ant*q[i] <= j)dp2[j]=min(dp2[j],dp2[j-ant*q[i]]+ant);}}int minn=MAXX;for(i=t;i<=10000;i++){if(minn>dp2[i]+dp1[i-t]) minn=dp2[i]+dp1[i-t];}if(minn != MAXX )printf("%d\n",minn);else printf("-1\n");}return 0;}

路途中。。。。。。。


原创粉丝点击