1014 Dividing dp/dfs
Posted sweet-ginger-candy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1014 Dividing dp/dfs相关的知识,希望对你有一定的参考价值。
先用dfs方法:(注意剪枝的重要性)
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int sumvalue,halfvalue; int n[7]; bool flag;//记录是否能够进行平分。 void dfs(int value,int c) if(flag) return; if(value==halfvalue) flag=true; return; for(int i=c;i>=1;i--) if(n[i]) if(value+i<=halfvalue)//注意<=号的意义 n[i]--; dfs(value+i,i); if(flag) break; return ; int main() int k=0; while(true) sumvalue=0;//注意sumvalue初始化的位置,而且必须进行初始化。 k++; for(int i=1;i<=6;i++) cin>>n[i]; sumvalue+=(i*n[i]); if(sumvalue==0) break; if(sumvalue%2!=0)//为真 cout<<"Collection #"<<k<<":"<<endl; cout<<"Can‘t be divided."<<endl; cout<<endl; continue; halfvalue=sumvalue/2; flag=false;//为了验证dfs的效果。 dfs(0,6); if(flag) cout<<"Collection #"<<k<<‘:‘<<endl; cout<<"Can be divided."<<endl<<endl; continue; else cout<<"Collection #"<<k<<‘:‘<<endl; cout<<"Can‘t be divided."<<endl<<endl; continue; return 0;
多重背包+二进制优化
来源:https://blog.csdn.net/lyy289065406/article/details/6661449
#include<iostream> using namespace std; int n[7]; //价值为i的物品的个数 int v; //背包容量 int SumValue; //物品总价值 bool flag; //标记是否能平分SumValue int dp[100000]; //状态数组 int max(int a,int b) return a>b?a:b; /*完全背包*/ 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) //剪枝,当能够平分SumValue时退出 flag=true; return; return; /*01背包*/ 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(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; 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) 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;
以上是关于1014 Dividing dp/dfs的主要内容,如果未能解决你的问题,请参考以下文章