coins(hdu 3348 贪心 + 多重背包)

来源:互联网 发布:用java打印对称三角形 编辑:程序博客网 时间:2024/05/29 04:34

用多重背包写总是超时,看了大神的思路。。。

一开始我完全用多重背包,超时。。。

后来一开始用贪心求出最小张数,然后把多重背包转化成01背包和完全背包,再次超时。。。

再然后就是下面的代码了,但是背包比起完全用贪心写还是太慢了。


#include<iostream>#include<stdio.h>#include<math.h>#include<string.h>#include<vector>#include<list>#include<algorithm>using namespace std;#define MAX 1000010int p;int a[6];int v[6] = {1,5,10,50,100};int dpu[MAX]; int conut[MAX];void MP(int value,int n);void findu();int findl();int MIN;int main(){int T;scanf("%d",&T);while(T--){scanf("%d",&p); for(int i=0;i<5;i++){scanf("%d",&a[i]);}if(findl()){printf("%d ",MIN);/*for(int i=0;i<=p;i++){dpu[i] = -0x3f3f3f3f;}dpu[0] = 0;for(int i=0;i<5;i++){MP(v[i],a[i]);}*/findu();if(dpu[p]>=0){printf("%d\n",dpu[p]);}else{printf("-1\n");}}else{printf("-1 -1\n");}} return 0;}void findu(){ int i,j; memset(dpu,-100,4*(p+1)); dpu[0]=0; for(i=0;i<5;i++){memset(conut,0,4*(p+1));for(j=v[i];j<=p;j++){if(dpu[j]<dpu[j-v[i]]+1 && conut[j-v[i]]<a[i]){    dpu[j]=dpu[j-v[i]]+1;    conut[j]=conut[j-v[i]]+1;}}}}//先用贪心求出最小张数 int findl(){int num = 0;int c = p;for(int i=4;i>=0;i--){int t = c/v[i];if(t<=a[i]){num += t;c -= t*v[i];}else{num += a[i];c -= a[i]*v[i];}if(c==0){MIN = num;return 1;}}return 0;}//用这种多重背包的写法(转换成01背包和完全背包)会超时 void CP(int value){for(int i=value;i<=p;i++){dpu[i] = max(dpu[i],dpu[i-value] + 1);}}void ZOP(int value,int n){for(int i=p;i>=value;i--){dpu[i] = max(dpu[i],dpu[i-value] + n);}}void MP(int value,int n){if(n*value>=p){CP(value);}else{int k=1;while(k<=n){ZOP(value*k,k);n-=k;k*=2;}ZOP(value*n,n);}}


0 0
原创粉丝点击