poj1014 Dividing
2013-05-01 15:25
330 查看
某书上的代码
#include<stdio.h> #include<string.h> int a[7]; void dp(int sum){ int i,j,k; int mid=sum/2; char vis[200]; memset(vis,0,sizeof(vis)); int t; vis[0]=1; for(i=1;i<=6;i++) for(j=mid;j>=0;j--) if(vis[j]) for(k=1;k<=a[i];k++){ t=j+i*k; if(t>mid) break; else vis[t]=1; if(t==mid){ printf("Can be divided.\n\n"); return ; } } printf("Can't be divided.\n\n"); } int main(){ int i; int icase=1; while(1){ int sum=0; for(i=1;i<=6;i++){ scanf("%d",&a[i]); if(a[i]!=0&&a[i]%6==0) a[i]=6; else a[i]%=6; sum+=a[i]*i; } if(sum==0) break; printf("Collection #%d:\n",icase++); if(sum%2){ printf("Can't be divided.\n\n"); continue; } dp(sum); } return 0; }某神套用背包模板的方法,该模板来自背包九讲
#include<iostream> #include<cstring> #include<cstdio> #define max(a,b) a>b?a:b using namespace std; int n[7]; int v; int sumvalue; bool flag; int dp[100000]; void completepack(int cost,int weight){ for(int i=cost;i<=v;i++){ dp[i]=max(dp[i],dp[i-cost]+weight); if(dp[i]==v){ flag=true; return; } } return; } void zeroonepack(int cost,int weight){ for(int i=v;i>=cost;i--){ dp[i]=max(dp[i],dp[i-cost]+weight); if(dp[i]==v){ flag=true; return; } } return; } void multiplepack(int cost,int weight,int amount){ if(cost*amount>=v){ completepack(cost,weight); return; } if(flag) return; int k=1; while(k<amount){ zeroonepack(k*cost,k*weight); if(flag) return; amount-=k; k*=2; } zeroonepack(amount*cost,amount*weight); return; } int main(){ int i; int test=1; while(scanf("%d%d%d%d%d%d",&n[1],&n[2],&n[3],&n[4],&n[5],&n[6])){ sumvalue=0; for(i=1;i<=6;i++){ if(n[i]!=0&&n[i]%6==0) n[i]=6; else n[i]=n[i]%6; sumvalue+=i*n[i]; } if(sumvalue==0) break; if(sumvalue%2){ printf("Collection #%d:\n",test++); printf("Can't be divided.\n\n"); continue; } v=sumvalue/2; memset(dp,-1,sizeof(dp)); dp[0]=0; flag=false; for(i=1;i<=6;i++){ multiplepack(i,i,n[i]); if(flag) break; } if(flag){ printf("Collection #%d:\n",test++); printf("Can be divided.\n\n"); continue; } else{ printf("Collection #%d:\n",test++); printf("Can't be divided.\n\n"); continue; } } return 0; }该神还用dfs() A过去了,贪心性质的dfs(),并没有枚举所有状态,只枚举了极少状态,先用价值最大的填充,价值大的用光了或装不进去了就换次大的,赤裸裸的贪心啊,一定没有回溯,否则会tle,至于为什么可以这样做...
#include<iostream> using namespace std; int n[7]; //价值为i的物品的个数 int SumValue; //物品总价值 int HalfValue; //物品平分价值 bool flag; //标记是否能平分SumValue void DFS(int value,int pre) { if(flag) return; if(value==HalfValue) { flag=true; return; } for(int i=pre;i>=1;i--) { if(n[i]) { if(value+i<=HalfValue) { n[i]--; DFS(value+i,i); if(flag) break; } } } return; } int main(int i) { int test=1; while(cin>>n[1]>>n[2]>>n[3]>>n[4]>>n[5]>>n[6]) { SumValue=0; //物品总价值 for(i=1;i<=6;i++) SumValue+=i*n[i]; if(SumValue==0) break; if(SumValue%2) //sum为奇数,无法平分 { cout<<"Collection #"<<test++<<':'<<endl; cout<<"Can't be divided."<<endl<<endl; //注意有空行 continue; } HalfValue=SumValue/2; flag=false; DFS(0,6); if(flag) { cout<<"Collection #"<<test++<<':'<<endl; cout<<"Can be divided."<<endl<<endl; continue; } else { cout<<"Collection #"<<test++<<':'<<endl; cout<<"Can't be divided."<<endl<<endl; continue; } } return 0; }上两种方法转自/article/1968966.html
相关文章推荐
- POJ 1014 Dividing 多重背包
- POJ 1014 Dividing
- POJ 1014 Dividing 解答
- poj 1014 Dividing 多重背包 二进制拆分
- POJ 1014 Dividing
- poj1014 hdu1059 Dividing 多重背包
- Dividing poj 1014
- POJ 1014 Dividing (母函数优化)
- POJ1014:Dividing
- poj 1014 dividing(本解法可ac 但错误!!!)
- POJ 1014 Dividing (多重背包)
- 【poj1014】 Dividing
- poj 1014 Dividing
- POJ 1014 Dividing
- POJ 1014 Dividing 多重背包
- POJ 1014 Dividing
- poj 1014 Dividing (dfs???)
- 多重背包(包含0-1,完全和多重背包的函数模板)POJ1014-Dividing-多重背包
- poj 1014 Dividing 背包问题(dfs)(其实我用最笨的方法写的)
- POJ 1014 Dividing (多重背包问题)