hduoj 1455 && 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     Memory Limit:0KB     64bit IO Format:%lld & %llu

题目描述:

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 file contains blocks of 2 lines. The first line contains the number of sticks parts after cutting. 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

9
5 2 1 5 2 1 5 2 1
4
1 2 3 4
0

Sample Output

6
5

分析:uva会TLE , hduoj AC


AC代码:
 1 #include<algorithm>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<iostream>
 5 using namespace std;
 6
 7 const int N = 1e4+10;
 8 int len[N],sum,L,T;
 9 int used[N];
10
11 int cmp(const void *a,const void *b)
12 {
13      return *(int *)b-*(int *)a;
14 }
15
16 bool DFS(int m,int left)
17 //m为剩余的木棒数,left为当前正在拼接的木棒和假定的木棒长度L还缺少的长度
18 {
19     if(m == 0 && left == 0)
20         return true;
21     if(left == 0)//一根刚刚拼完
22         left = L;
23     for(int i=0; i<T; i++)
24     {
25        if(!used[i] && len[i]<=left)
26         {
27             if(i>0)//如果前者已经出现过的不能用,则当前的也不能用
28             {
29                 if(!used[i-1] && len[i] == len[i-1])
30                     continue;
31             }
32             used[i] = 1;
33             if(DFS(m-1,left-len[i]))
34                 return true;
35             else
36             {
37                 used[i] = 0;
38                 if(len[i] == left || left == L)
39                     return false;
40             }
41         }
42     }
43     return false;
44 }
45
46 int main()
47 {
48     while(scanf("%d",&T) && T)
49     {   sum  = 0 ;
50         for(int i=0;i<T;i++)
51         {
52             scanf("%d",&len[i]);
53             sum = sum + len[i];
54         }
55         //sort(len,len+T,cmp);          sort  超时
56         qsort(len,T,sizeof(int),cmp);       //从大到小排序
57         for(L = len[0];L<=sum/2;L++)
58         {
59             if(sum%L)
60                 continue;
61             memset(used,0,sizeof(used));
62             if(DFS(T,L))
63             {
64                 printf("%d\n",L);
65                 break;
66             }
67         }
68         if(L>sum/2)
69             printf("%d\n",sum);
70     }
71     return 0;
72 }
时间: 2024-07-28 20:49:20

hduoj 1455 && uva 243 E - Sticks的相关文章

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

UVA 10003 - Cutting Sticks

#include<iostream> #include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; in

UVA - 10003 —— Cutting Sticks

很基础的一道区间DP :) #include <cstdio> #include <iostream> #define INF 0x3f3f3f3f using namespace std; int c[1005]; int dp[1005][1005]; int main () { int l, n; while(scanf("%d", &l)!=EOF && l) { scanf("%d", &n); fo

UVA 10003 cuting sticks 切木棍

区间dp,切割dp[i][j]的花费和切法无关(无后效性) dp[i][j]表示区间i,j的花费,于是只要枚举切割方法就行了,区间就划分成更小的区间了.O(n^3) 看了看四边形不等式,证明太长了. #include<bits/stdc++.h> //变量不要取成ignore left之类 using namespace std; const int maxn = 51; int cut[maxn]; int dp[maxn][maxn]; const int INF = 0x3fffffff

Uva 10003 Cutting Sticks (类似于最优矩阵连乘的dp)

题意:有一根长度为L的木棍,和n个切割点的位置(按照从小到大排序),你的任务是在这些切割点的位置把棍子切成n+1份,使得总切割费用最小.每次切割的费用等于被切的木棍长度 思路:这道题与最优矩阵连乘的思想一样,那就是分析最优子结构,再根据子结构来定义状态,首先我们假定第一次分割的最优方案是在k处分割,得到0~k与k~L两段木棍,那么如何最优分割0~k与0~L就是它的子问题,我们根据子问题定义状态d(i,j)是分割从割点i到割点j的最优方案,状态转移方程 d(i,j)=min{d(i,k)+d(k,