博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu Sticks
阅读量:5030 次
发布时间:2019-06-12

本文共 3000 字,大约阅读时间需要 10 分钟。

Sticks

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 206    Accepted Submission(s): 67
 
Problem Description
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.
 
Input
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.
 
Output
The output file contains the smallest possible length of original sticks, one per line.
 
Sample Input
95 2 1 5 2 1 5 2 141 2 3 40
 
Sample Output
65
 
 
Source
ACM暑期集训队练习赛(七)
 
Recommend
lcy

分析:去年做完全没思路,今天增加一个关键剪枝后0msAC。

此题关键:逆序快排一次,因为长度与灵活度成反比。

关键剪枝:每次构造新木棍时,未用的最大的小木棍必须使用。

其他剪枝:在构造某根小木棒时,相同的长度未用的只搜一次。

#include
#include
#include
using namespace std;int st[70];int vis[70];int len, tot;int n;bool cmp(int a, int b) { return a>b;}int dfs(int now, int num, int pos) { if (num == tot) return 1; int i, t; if (now == 0) { while (vis[pos]) ++pos; vis[pos] = 1; if (st[pos] == len) { if (dfs(0, num + 1, 0)) return 1; else { vis[pos] = 0; return 0; } } else { if (dfs(st[pos], num, pos + 1)) return 1; else { vis[pos] = 0; return 0; } } } for (i = pos; i < n; ++i) { if (i > 0 && !vis[i - 1] && st[i] == st[i - 1]) continue; if (!vis[i]) { t = now + st[i]; if (t == len) { vis[i] = 1; if (dfs(0, num + 1, 0)) return 1; else { vis[i] = 0; return 0; } } else if (t < len) { vis[i] = 1; if (dfs(t, num, i + 1)) return 1; vis[i] = 0; } } } return 0;}int main() { int i, sum; while (scanf("%d", &n) != EOF && n) { sum = 0; for (i = 0; i < n; ++i) { scanf("%d", &st[i]); sum += st[i]; } sort(st, st + n, cmp); for (len = st[0]; len < sum; ++len) { if (sum % len == 0) { memset(vis, 0, sizeof (vis)); tot = sum / len; if (dfs(0, 0, 0)) { break; } } } printf("%d\n", len); } return 0;}

 

转载于:https://www.cnblogs.com/baidongtan/archive/2012/09/01/2666257.html

你可能感兴趣的文章
[TMS320C674x] 一、GPIO认识
查看>>
酷狗的皮肤文件存放在哪
查看>>
iOS RunLoop简介
查看>>
C++的引用
查看>>
T-SQL查询进阶--深入浅出视图
查看>>
MapKeyboard 键盘按键映射 机械革命S1 Pro-02
查看>>
Android读取url图片保存及文件读取
查看>>
完整ASP.Net Excel导入
查看>>
判断CPU大小端示例代码
查看>>
ARTS打卡第13周
查看>>
循环队列的运用---求K阶斐波那契序列
查看>>
pta 编程题14 Huffman Codes
查看>>
初始化bootstrap treeview树节点
查看>>
python selenium向<sapn>标签中写入内容
查看>>
JS常用坐标
查看>>
使用”结构化的思考方式“来编码和使用”流程化的思考方式“来编码,孰优孰劣?...
查看>>
C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)【转】...
查看>>
关于git的认证方式
查看>>
字符串按照字典序排列
查看>>
IOS 开发调用打电话,发短信
查看>>