[poj 1014]Dividing的DFS解法解读和DP解法
转载来源:
http://blog.csdn.net/lyy289065406/article/details/6661449
这道题比较特殊,用DFS也是对的,而且可以进行优化,即使直接n[i]--也是对的.解释见注释.
//Memory Time//440K 16MS/*DFS*/#include<iostream>using namespace std;int n[7]; //价值为i的物品的个数int SumValue; //物品总价值int HalfValue; //物品平分价值bool flag; //标记是否能平分SumValuevoid DFS(int value,int pre){if(flag)return;if(value==HalfValue){flag=true;return;}
//为什么可以n[i]--而不回溯呢?
//因为只要从剩下的物品中选出一半,那么尝试失败的那些选择都可以认为是给了对方。
//因为从分叉点之下,失败的代价总是在剩下的half之内.
//如果回溯的话就会TLE了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 test=1;while(cin>>n[1]>>n[2]>>n[3]>>n[4]>>n[5]>>n[6]){SumValue=0; //物品总价值for(int 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;}
分析不清楚的时候1可借助小规模实例,2可借助debug单步
下面是更通用的DP解法~
//Memory Time
//644K 0MS /*多重背包+二进制优化*/ #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,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;
}
[poj 1014]Dividing的DFS解法解读和DP解法相关推荐
- POJ 1014: Dividing
写在前面: 本题非常有意思, 因此我在编程前后和撰写本文前, 在网上查询并阅读了大量关于本题的解题报告. 当中有两种似是而非但提交后却可以 AC 的解法引起了我的兴趣, 一是原作者宣称的 " ...
- POJ 1014 Dividing
套模板+填参数=AC POJ还是用C++提交靠谱 Dividing Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 51256 A ...
- POJ 1014 Dividing(多重背包 + 倍增优化)
题意: 求一种划分方案使结果最公平. 思路: 多重背包,然后把物品分为 2^0, 2^1, ... , 2^k,... 等. #include <iostream> #include &l ...
- POJ 1014 Dividing 背包
二进制优化,事实上是物体的分解问题. 就是比方一个物体有数量限制,比方是13,那么就须要把这个物体分解为1. 2, 4, 6 假设这个物体有数量为25,那么就分解为1, 2, 4. 8. 10 看出规 ...
- POJ 1014 Dividing【多重背包+二进制优化】
大意: 价值1, 2, 3, --, 6的物品分别a1, a2, --, a5, a6件 问能否把这些物品分成两份,使其具有相同的价值(所有物品必须全部用上) 分析: 给个物品有多件,即多重背包 只要 ...
- 【POJ】 1014 Dividing(多重背包,优化)
[POJ] 1014 Dividing(多重背包,优化) [题目链接]http://poj.org/problem?id=1014 题目 Description Marsha and Bill own ...
- 仙人掌相关问题的解法(1)-DFS树解决仙人掌DP问题,圆方树
前言 有难度的仙人掌题在近几年也只是在国家集训队水平的比赛里才会出现. 不过,这不是说仙人掌对国集水平以下的选手意义不大: 首先,仙人掌暴力 DP 问题难度并不大,在省选. NOI 甚至 NOIP 中 ...
- python堆栈汉诺塔非递归_汉诺塔问题的递归解法和非递归解法(python语言实现)...
汉诺塔问题的非递归解法(python语言类解法) #!/usr/bin/env python #coding:utf-8 import sys import time reload(sys) sys. ...
- 紧凑存储的杜利特尔分解法Doolittle(LU分解法)_解线性方程组的直接解法
紧凑存储的杜利特尔分解法Doolittle(LU分解法)_解线性方程组的直接解法 标签:计算方法实验 /* 紧凑存储的杜利特尔分解法Doolittle:如果初始矩阵不要求保留的话,可以紧凑存储.因为每 ...
最新文章
- 快乐学算法之:字典树Trie
- 名词解释计算机网络体系结构,计算机网络技术题库(带答案).doc
- GIT项目管理工具(part3)--初始化仓库及查看仓库状况
- idea for mac 控制台 mvn command not found
- lamp和php,[LAMP]Apache和PHP的结合
- 海洋分享lol皮肤插件_LOL战斗之夜客户端BUG频出服务器爆满!如何提前领取皮肤?...
- C++调pytorch模型的全过程记录
- 多元相关性分析_电子健康素养与中青年脑卒中患者健康行为的相关性分析
- java发送http跨域_跨域发送HTTP请求详解
- 华为P30系列高清渲染图曝光:后置三摄拍照要上天
- 《CSS权威指南》.pdf
- 服务器安全基础知识系列(三)关于网页木马
- 警务综合平台情报研判应用建设方案
- matlab泰勒公式近似值,泰勒公式及其在在计算方法中的应用.doc
- jsonp跨域获取数据
- win7 网络不显示电脑连接到服务器,Win7在网上邻居上看不到别的电脑怎么办?
- 谈谈 .NET Reflector
- Go语言操作excel
- 无言的结局......
- MyHDL中文手册(十)——转换成Verilog和VHDL