poj 1011 sticks
来源:互联网 发布:安卓捏人软件 编辑:程序博客网 时间:2024/06/03 18:02
题意:已知木棍的数量和长度,求这些木棍的最小原始长度。
参考了网上的解题报告,用DFS+剪枝解决,共用到6个剪枝,用时16MS。
代码如下:
#include<iostream>#include<algorithm>using namespace std;#define SIZE 65int stick[SIZE];int visited[SIZE];int n;int dfs(int i,int sum,int curlen,int initlen,int stick[]){ if (sum == n) return true; int sample = -1; for (int j =i; j < n; j++){ if (!visited[j] && sample !=stick[j] ){ //剪枝4:如果一个棍子不行,则与它等长的棍子也不行 visited[j] = 1; if (curlen+stick[j] <initlen){ if (dfs(j,sum + 1, curlen + stick[j], initlen, stick)) return true; else sample =stick[j]; } if (curlen+stick[j] ==initlen){ if(dfs(0,sum + 1, 0, initlen, stick)) return true; else sample =stick[j]; } visited[j] = 0; if (curlen == 0)//剪枝5:对于新棍的第一根棍子,搜索完所有棍子后都无法组合,返回上一层 break; if (stick[j] ==initlen - curlen)//剪枝6:当前棍子长度=剩余所需长度,但后面搜索失败,返回上一层 break; } } return false;}int cmp(const int a,const int b){ return a>b;}int main(){ while (cin >> n){ bool flag = 0; if (n == 0) break; int sumlen = 0; for (int i = 0; i < n; i++){ cin >> stick[i]; sumlen += stick[i]; visited[i] = 0; } sort(stick, stick+n, cmp); //剪枝1:从大到小排列,减少递归次数 int maxlen = stick[0]; for (int initlen = maxlen; initlen <= sumlen/2; initlen++){ //剪枝2:initlen最大为sumlen/2,最小为maxlen if (sumlen % initlen == 0 && dfs(0, 0, 0, initlen, stick)){//剪枝3:sumlen能被initlen 整除 cout << initlen << endl; flag = true; break; } } if (flag ==false) cout << sumlen << endl; } return 0;}
0 0
- poj 1011-sticks
- POJ 1011 Sticks
- poj 1011 Sticks
- poj 1011 Sticks
- POJ 1011 Sticks
- poj 1011 Sticks
- POJ 1011 Sticks
- poj 1011 sticks
- POJ 1011 Sticks
- poj 1011 sticks
- POJ 1011 Sticks
- POJ 1011: Sticks
- poj 1011 Sticks
- poj 1011 Sticks【dfs】
- hdu1455 poj 1011 sticks
- poj 1011 Sticks
- POJ 1011 Sticks
- POJ 1011 Sticks
- Rendering Problems(布局渲染错误)
- shell 命令——paste用法
- 我的第一篇博客
- Mac下安装mysql5.7 完整步骤(图文详解)
- mysql 主主同步
- poj 1011 sticks
- 使用Docker构建redis集群
- Android OkHttpClient
- IDEA历史版本下载
- springmvc中的ssm
- 平衡查找树
- Lua FFI 实战
- java调用NSQ消息服务
- PTA习题 两个有序链表序列的交集