poj 1742 多重背包变种 对时间要求特别严格
2013-09-05 18:24
176 查看
1 多重背包物品二进制拆分后01背包
2 按照之前网上说的思路尝试优化,但依然不理想,依然TLE.
3 参考
/article/10277896.html
混合 完全背包和01背包优化解决多重背包问题
如果一个物品的value*amount >= m时,则认为此物品可以取任意多件,因为在物品的件数限制amount内,一定可以满足m了。
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; #define MAX_V (100+1) #define MAX_F (100000+1) int A[MAX_V],C[MAX_V]; int Value[MAX_F]; bool F[MAX_F]; int n,m; #define printf // int main() { while(scanf("%d %d",&n,&m) != EOF) { if(n==0 && m== 0) return 0; for(int i=1;i<=n;i++) { scanf("%d",&A[i]); //cin>>A[i]; } for(int i=1;i<=n;i++) { scanf("%d",&C[i]); //cin>>C[i]; } int cnt = 0; //binary拆分物品 //C数量 A价值 for(int i=1;i<=n;i++) { printf("old:数量:%d 价值:%d\n",C[i],A[i]); int tc = C[i]; for(int k=1;k<=tc; k <<= 1) { Value[cnt++] = A[i] *k; tc -= k; printf("\t\t %d:价值:%d \n",k,k*A[i]); } if(tc > 0) { Value[cnt++] = A[i] * tc; printf("\t\t%d:价值:%d\n",C[i],C[i]*A[i]); } } memset(F,0,sizeof(F)); F[0]=true; for(int i=0;i<cnt;i++) { //for(int v=m;v>Value[i];v--) for(int v=m;v>=Value[i];v--) { if(F[v]) continue; if(F[v-Value[i]]) F[v] = true; //F[v] = F[v] || F[v-Value[i]]; printf("i=%d(%d) F[v-x]=%d F[%d]=%d\n",i,Value[i],F[v-Value[i]],v,F[v]); // if(F[v - Value[i] ] + value[i] > F[v]) // F[v] = F[v - value[i] ] + value[i]; } } int sums = 0; for(int v=m;v>0;v--) if(F[v]) { ++sums; } cout<<sums<<endl; } }
2 按照之前网上说的思路尝试优化,但依然不理想,依然TLE.
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; #define MAX_V (100+1) #define MAX_F (100000+1) int A[MAX_V],C[MAX_V]; int Value[MAX_F]; bool F[MAX_F]; //F[v]为使用i能否达到v int n,m; #define printf // int main() { while(scanf("%d %d",&n,&m) != EOF) { if(n==0 && m== 0) return 0; for(int i=1;i<=n;i++) { scanf("%d",&A[i]); //cin>>A[i]; } for(int i=1;i<=n;i++) { scanf("%d",&C[i]); //cin>>C[i]; } memset(F,0,sizeof(F)); F[0]=true; int maxv = 0; int sum = 0; for(int i=1;i<=n;i++) { for(int v=maxv;v>=0;v--) { if(F[v]) { for(int k=1;k<= C[i];k++) { int ki = v+ k*A[i]; if(ki >m ) break; if(F[ki]) continue; ++sum; F[ki]= true; if(ki > maxv) maxv = ki; } } } } // int sums = 0; // for(int v=m;v>0;v--) // { // printf("%d=%d\n",v,F[v]); // if(F[v]) // { // ++sums; // } // } cout<<sum<<endl; } }
3 参考
/article/10277896.html
混合 完全背包和01背包优化解决多重背包问题
如果一个物品的value*amount >= m时,则认为此物品可以取任意多件,因为在物品的件数限制amount内,一定可以满足m了。
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; #define MAX_V (100+1) #define MAX_F (100000+1) int A[MAX_V],C[MAX_V]; bool F[MAX_F]; int n,m; #define printf // void ZeroOnePack(int value) { printf("zero one pack value:%d\n",value); for(int v=m;v>=value;--v) { F[v] |= F[v-value]; printf("F[%d] = %d\n",v,F[v]); } } void CompletePack(int value) { for(int v=value;v<=m;v++) //完全背包和01背包只有循环顺序不同,具体可参考背包问题九讲 F[v] |= F[v-value]; } void MultiPack(int value,int amount) { if(value * amount >= m) { CompletePack(value); return; } //这段对某些可以应用完全背包的物品,进行完全背包才最终AC的。 int k=1; while(k<amount) { ZeroOnePack(value * k); amount -= k; k <<= 1; } if(amount) ZeroOnePack(value*amount); } int main() { while(scanf("%d %d",&n,&m) != EOF) { if(n==0 && m== 0) return 0; for(int i=1;i<=n;i++) { scanf("%d",&A[i]); } for(int i=1;i<=n;i++) { scanf("%d",&C[i]); } memset(F,0,sizeof(F)); F[0] = true; //数量c for(int i=1;i<=n;i++) { if(C[i]) { MultiPack(A[i],C[i]); } } int sums = 0; for(int v=m;v>0;v--) if(F[v]) { ++sums; } cout<<sums<<endl; } }
相关文章推荐
- POJ 1742(特别技巧之多重背包转完全背包)
- POJ-1742-多重背包-Coins
- POJ 1742 Coins (背包)
- POJ 1742 Coins 多重背包单调队列优化
- hdu2844 & poj1742 Coin ---多重背包--两种方法
- (优化的有限背包) poj 1742 Coins
- (不易)POJ-1742 多重部分和,多重背包可行性
- poj1742(背包问题)
- [POJ 1742] Coins 男人八题(多重背包)
- poj-1742 Coins(多重背包优化)
- POJ1742 Coins(背包)
- poj 1742coins(优化的多重背包)
- poj_2392_Space Elevator & poj_1742_Coins 一种多重背包
- linux 设置时间(hadoop 对于时间要求比较高,所有在集群时特别要注意时间)
- poj 1742 Coins (背包)
- poj 1742 Coins dp 多重背包 优化
- POJ 1742 Coins 【多重背包DP】
- POJ1742 多重背包 递推关系优化
- poj1742 单调队列优化多重背包
- POJ 1742 Coins (多重背包)