POJ 1011/DFS:子集划分
2011-06-06 18:48
253 查看
问题描述:原有若干sticks,每支stick被分割成若干支,现在要恢复一下。找出这样的子集,使得每个子集的和(plen)相等,并且最小
算法:排序,遍历所有可能plen剪枝:排序后, a[0] a[1] a[2].....a[n-1],如果想从a[i]开始(不包括i)匹配一个数v,如果i+1,i+2......n-1都匹配不成功了,则肯定i+2,i+3....n-1也匹配不成功了,所以从TLE版本做修改后得到AC版本
TLE:#include <iostream> #include <algorithm> using namespace std; #define MAX 64 int sticks[MAX]; bool used[MAX]; int stickNum,plen,n; bool compare(int a, int b) { return a > b; } //从beginIndex号开始匹配,下一步要匹配matchLen的stick,在此之前已经匹配了hasMatch条stick bool dfs(int beginIndex,int matchLen,int hasMatch){ //printf("%4d%4d%4d\n",beginIndex,matchLen,hasMatch); if(matchLen==0){ hasMatch++; //printf("hasMatch=%d,stickNum=%d\n",hasMatch,stickNum); if(hasMatch==stickNum){ //printf("hasMatch==stickNum\n"); return true; } for(beginIndex=0;used[beginIndex];beginIndex++); //used[beginIndex]=true; //printf("match=%d begin = %d\n",hasMatch,beginIndex); if(dfs(beginIndex,plen,hasMatch))return true; //used[beginIndex]=false; return false; }else{ if(beginIndex>n-1)return false; for(int i=beginIndex;i<n;i++){ if(used[i])continue; if(sticks[i]>matchLen)continue; if(i>0&&sticks[i]==sticks[i-1]&&!used[i-1])continue; used[i]=true; if(dfs(i+1,matchLen-sticks[i],hasMatch)) return true; used[i]=false; } } //printf("end %4d%4d%4d false\n",beginIndex,matchLen,hasMatch); return false; } int main(int argc, char* argv[]) { int sum = 0; int i; while(scanf("%d",&n)&&n){ sum=0; for( i=0;i<n;i++){ scanf("%d",&sticks[i]); sum += sticks[i]; } bool ok = false; sort(sticks,sticks+n,compare); for(plen=sticks[0];plen<=sum/2;plen++){ if(sum%plen==0){ //used[0]=true; stickNum = sum/plen; if(dfs(0,plen,0)){ ok = true; break; } //used[0]=false; } } if(ok){ printf("%d\n",plen); }else{ printf("%d\n",sum); } memset(used,false,sizeof(used)); } return 0; }AC:
#include <iostream>#include <algorithm>using namespace std;#define MAX 64int sticks[MAX];bool used[MAX];int stickNum,plen,n;bool compare(int a, int b){return a > b;}//从beginIndex号开始匹配,下一步要匹配matchLen的stick,在此之前已经匹配了hasMatch条stickbool dfs(int beginIndex,int matchLen,int hasMatch){//printf("%4d%4d%4d\n",beginIndex,matchLen,hasMatch);if(matchLen==0){hasMatch++;//printf("hasMatch=%d,stickNum=%d\n",hasMatch,stickNum);if(hasMatch==stickNum){//printf("hasMatch==stickNum\n");return true;}for(beginIndex=0;used[beginIndex];beginIndex++);//printf("match=%d begin = %d\n",hasMatch,beginIndex);used[beginIndex]=true;if(dfs(beginIndex+1,plen-sticks[beginIndex],hasMatch))return true;used[beginIndex]=false;return false;}else{if(beginIndex>n-1)return false;for(int i=beginIndex;i<n;i++){if(used[i])continue;if(sticks[i]>matchLen)continue;if(i>0&&sticks[i]==sticks[i-1]&&!used[i-1])continue;used[i]=true;if(dfs(i+1,matchLen-sticks[i],hasMatch))return true;used[i]=false;}}//printf("end %4d%4d%4d false\n",beginIndex,matchLen,hasMatch);return false;}int main(int argc, char* argv[]){//freopen("i://in.txt","r",stdin);int sum = 0;int i;while(scanf("%d",&n)&&n){sum=0;for( i=0;i<n;i++){scanf("%d",&sticks[i]);sum += sticks[i];}bool ok = false;sort(sticks,sticks+n,compare);for(plen=sticks[0];plen<=sum/2;plen++){if(sum%plen==0){used[0]=true;stickNum = sum/plen;if(dfs(0,plen-sticks[0],0)){ok = true;break;}used[0]=false;}}if(ok){printf("%d\n",plen);}else{printf("%d\n",sum);}memset(used,false,sizeof(used));}return 0;}
相关文章推荐
- poj 1011 DFS+剪枝
- POJ 1011 (DFS)
- POJ1011 Sticks(dfs)
- poj 1011 Sticks解题报告【DFS+剪枝】
- POJ 1011 Sticks(dfs)
- poj 1011/2362 dfs+剪枝(拼木棍)
- [POJ-1011] DFS
- POJ 1011/HDU 1455 dfs 剪枝
- poj 1011 Sticks【dfs】
- 【DFS剪枝】poj 1011 Sticks
- poj 1011 Sticks (DFS+剪枝)
- POJ 2362 square &&POJ 1011 Sticks 记忆化搜索 DFS
- [POJ 1011]Sticks(DFS剪枝)
- poj 1011 Sticks (DFS+剪枝)
- POJ 1011 Sticks (经典DFS)
- poj 1011 Sticks (经典dfs)
- POJ1011 Sticks【DFS+剪枝】
- poj dfs相关之1011 Sticks
- POJ 1011 Sticks【dfs】
- hdu 1455/poj 1011 Sticks(DFS剪枝神题)