UVA-307 Sticks

超时了好多次,一开始枚举子集,最后的做法是先算出可能的答案,
在根据dfs判断,如果可能的答案可以把所有的木棍dfs掉即为所求。
注意剪枝优化。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 vector<int> sticks;
 4 int ans; int sum_len;
 5 int vis[200]; int n;
 6 int dfs(int num, int pos, int len){
 7     if(n == num)///成功把所有木棍dfs掉
 8         return 1;
 9     for(int i = pos ; i < sticks.size() ; i++) {
10         if(vis[i]) continue;
11         if(len + sticks[i] < ans){
12             vis[i] = 1;
13             if(dfs(num + 1, i + 1, len + sticks[i])) return 1;
14             vis[i] = 0;
15             while(i+1 < sticks.size() && sticks[i] == sticks[i+1]) i++;
16             if(len == 0) return 0;/// 如果len==0 代表没有合适的 返回 0;
17         }
18         else if(len + sticks[i] == ans){
19             vis[i] = 1;
20             if(dfs(num + 1, 0, 0)) return 1;
21             vis[i] = 0;
22             return 0;
23         }
24     }
25     return 0;
26 }
27 int main()
28 {
29     while(scanf("%d", &n) && n) {
30         sticks.resize(n);
31         sum_len = 0;
32         for(int i = 0 ; i < n ; i++){
33             scanf("%d", &sticks[i]);
34             sum_len += sticks[i];
35         }
36         sort(sticks.begin(),sticks.end(),greater<int>());//从大到小排序,可以跑得更快,让dfs中的长度尽快到达ans;
37         for(int i = n ; i > 0 ; i--) {
38             if(sum_len % i == 0) {
39                 ans = sum_len / i;
40                 memset(vis, 0, sizeof(vis));
41                 if(dfs(0,0,0)) {
42                     printf("%d\n", ans);
43                     break;
44                 }
45             }
46         }
47     }
48     return 0;
49 }
时间: 2024-12-14 05:51:58

UVA-307 Sticks的相关文章

uva 307 Sticks(回溯剪枝)

uva 307 Sticks 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 origi

UVA - 10003Cutting Sticks(递推)

题目:UVA - 10003Cutting Sticks(递推) 题目大意:给根木棍长度l,现在要锯这根木棍,给出n个锯点,求怎样锯才能使得开销最小.例如 长度为10的木棍, 锯点2 4 7,那么如果按照这个顺序 , 首先显示由长度位10的木头先锯了2 ,开销就加10,然后锯完现在有[0,2]和[2,10]长度分别为2 ,8的木棍,现在要在4这个位置锯木头,就是在长度为8的木头上锯4这个位置,这样就加上8,然后又有长度为[2,4][4,10]的木头,最后要锯7的话,就需要开销加上6.所以开销就是

Uva 10003-Cutting Sticks(区间DP)

题目链接:点击打开链接 题意: 一根长度为L 的木棒,要求要切割n次,给出n次需要切割的位置,每次切割花费为当前段的总长度.求最小花费. 思路:..一开始想了好久也没往区间DP那方面想QAQ.设 dp[i][j] 为切割[i,j] 区间的最小花费,状态转移方程为 dp[i][j]=max(dp[i][k-1]+dp[k+1][j]+a[j+1]-a[i-1]); #include <algorithm> #include <iostream> #include <cstrin

hduoj 1455 &amp;&amp; uva 243 E - Sticks

http://acm.hdu.edu.cn/showproblem.php?pid=1455 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=243 uva开头描述: 307 - Sticks Time limit: 3.000 seconds hduoj 开头描述: E - Sticks Time Limit:3000MS     Memo

UVA题目分类

题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics 10300 - Ecological Premium 458 - The Decoder 494 - Kindergarten Counting Game 414 - Machined Surfaces 490 - Rotating Sentences 445 - Marvelous Mazes

uva 10003 Cutting Sticks 简单区间dp

// uva 10003 Cutting Sticks 区间dp // 经典的区间dp // dp(i,j)表示切割小木棍i-j所需要的最小花费 // 则状态转移为dp(i,j) = min{dp(i,k) + dp(k,j) + a[j]-a[i]) // 其中k>i && k<j // a[j] - a[i] 为第一刀切割的代价 // a[0] = 0,a[n+1] = L; // dp数组初始化的时候dp[i][i+1]的值为 0,这表示 // 每一段都已经是切割了的,不

uva 10003 Cutting Sticks (DP)

uva 10003 Cutting Sticks Description 你的任务是替一家叫Analog Cutting Machinery (ACM)的公司切割木棍.切割木棍的成本是根据木棍的长度而定.而且切割木棍的时候每次只切一段.很显然的,不同切割的顺序会有不同的成本.例如:有一根长10公尺的木棍必须在第2.4.7公尺的地方切割.这个时候就有几种选择了.你可以选择先切2公尺的地方,然后切4公尺的地方,最后切7公尺的地方.这样的选择其成本为:10+8+6=24.因为第一次切时木棍长10公尺,

UVA 10003 Cutting Sticks(区间dp)

Description  Cutting Sticks  You have to cut a wood stick into pieces. The most affordable company, The Analog Cutting Machinery, Inc. (ACM), charges money according to the length of the stick being cut. Their procedure of work requires that they onl

uva 10003 Cutting Sticks 【区间dp】

题目:uva 10003 Cutting Sticks 题意:给出一根长度 l 的木棍,要截断从某些点,然后截断的花费是当前木棍的长度,求总的最小花费? 分析:典型的区间dp,其实和石子归并是一样的,花费就是石子的和,那么久不用多说了. AC代码: #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include <map> #include <

UVA 10003 Cutting Sticks 区间DP+记忆化搜索

UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的长度L,第二行是切割点的个数n,接下来的n行是切割点在木棍上的坐标. 输出切割木棍的最小费用 前话-区间dp简单入门 区间dp的入门下面博客写的非常好,我就是看的他们博客学会的,入门简单,以后的应用就得靠自己了. https://blog.csdn.net/qq_41661809/article/d