Sticks (剪枝)
来源:互联网 发布:js判断一个月有多少天 编辑:程序博客网 时间:2024/06/05 19:35
George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.
The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.
The output should contains the smallest possible length of original sticks, one per line.
95 2 1 5 2 1 5 2 141 2 3 40
65
问题分析:深搜+剪枝剪枝剪枝!!!已在代码中标注
第一种自己写的:
#include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>using namespace std;int vis[70];int stick[70];int len,flag,sum,n,s,pre;int cmp(int a,int b){return a>b;}void dfs(int length,int num){if (num==0){flag = 1;return ;}for(int i=0; i<n; i++){if (vis[i]==0){if (length+stick[i]<=len){length += stick[i];vis[i] = 1;if (length==len)dfs(0,num-1);elsedfs(length,num-1);if (flag)return ;length -= stick[i];vis[i] = 0; if (length==0)return ;if (stick[i]==stick[i+1]){while(stick[i]==stick[i+1] && i+1<n)i++;}}}}}int main(){while(~scanf("%d", &n)){if (n==0)return 0;s = 0;for(int i=0; i<n; i++){scanf("%d",&stick[i]);s += stick[i];}sort(stick,stick+n,cmp);memset(vis,0,sizeof(vis));flag = 0;for(len = stick[0]; len<=s; len++){if (s%len)continue;dfs(0,n);if (flag)break;}printf("%d\n",len); }return 0;}第二种写法:这里是参考网上的,没想懂在sum=0是为啥要单独讨论,不讨论就会超时
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<iostream>#include<algorithm>using namespace std;int slen[70];int total;int book[70];int len;int flag;int n;int cmp(int a,int b){return a>b;}void dfs(int t,int m,int sum)//t是用掉的小棒数量,m是接下来要摆放的小棒,sum为当前长度 {if (sum == 0){int cur = 0;while(book[cur])cur++;book[cur] = 1;dfs(t+1,cur+1,slen[cur]);book[cur] = 0;return ;} //如果当前长度已经达到枚举长度 if (sum == len){//如果小棒数量已经用完了if (t == n) flag = 1;//小棒没有用完 elsedfs(t,0,0);return ;} for(int i=m; i<n; i++){if (book[i] == 0 && sum + slen[i] <= len){//如果这一根与上一根相同并且上一根没有选,那么这一根也不选 if (book[i-1] == 0 && slen[i] == slen[i-1])continue;book[i] = 1;dfs(t+1,i+1,sum+slen[i]);book[i] = 0;//如果该小棒不能搭配,那么之后相同长度的小棒都不行 while(slen[i] == slen[i+1])i++;if (flag)return ;}}}int main(){while(~scanf("%d",&n)){if (n == 0)return 0;total = 0;for(int i=0; i<n; i++){scanf("%d",&slen[i]);total += slen[i];}sort(slen,slen+n,cmp);for(len=slen[0]; len<=total; len++){if (total % len == 0)//一定要是因数才能平分,否则大棍长度不可能相等{memset(book,0,sizeof(book));flag = 0;dfs(0,0,0);if (flag){printf("%d\n",len);break;}}}}return 0;}
0 0
- Sticks (剪枝)
- Sticks(DFS+剪枝+贪心)
- 307 - Sticks (深搜 + 剪枝)
- Sticks (dfs经典剪枝)
- JOJ1534: Sticks(麻烦的剪枝)
- poj 1011 sticks (dfs+剪枝)
- 307Sticks(*****)经典DFS+剪枝
- hdu 1455 Sticks (dfs 经典剪枝)
- uva 307 Sticks(DFS+ 剪枝)
- POJ 1011 Sticks ( 深搜、剪枝)
- [UVA 307] Sticks (DFS回溯 + 剪枝)
- uva:307 - Sticks(dfs + 剪枝)
- UVA - 307 Sticks(回溯+剪枝)
- uva 307 Sticks(回溯剪枝)
- UVa 307 - Sticks(暴力+剪枝)
- POJ 1011 Sticks(搜索剪枝)
- POJ - 1011 - Sticks (DFS + 剪枝)
- hdu 1455 Sticks(DFS+剪枝)
- Socket编程,如何保证外网环境下通信可靠无误
- 将博客搬至CSDN
- 洛谷P1468 派对灯 Party Lamps
- 反转链表
- 正确使用join语句
- Sticks (剪枝)
- 【JZOJ3737】【NOI2014模拟7.11】挖宝藏(treasure)
- Linux 服务器安装MySQL数据库
- 百度富文本编辑器的上传图片的路径问题
- CUDA之Dynamic Parallelism详解(二)
- zoomeye用户使用手册
- css Sprite
- nodejs:使用emailjs发送邮件
- Renting Bikes 二分