uva10003切木棍

有一根长度为L(L<1000)的棍子,还有n(n<50)个切割点的位置(按照从小到大排 列)。你的任务是在这些切割点的位置处把棍子切成n+1部分,使得总切割费用最小。每次 切割的费用等于被切割的木棍长度。

例如,L=10,切割点为2, 4, 7。如果按照2, 4, 7的顺序, 费用为10+8+6=24,如果按照4, 2, 7的顺序,费用为10+4+6=20。

很水的区间dp

先瞎推了个伪转移方程

f(i,j)=min(f(i,k)+f(k,j)+l(i,j))

开始瓜了,试图用二重循环预处理l(i,j)

不要重蹈覆辙

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e6+5;
 4 const int INF=1e9+5;
 5 int l,n,f[105][105],a[1005];
 6 template <class t>void red(t &x)
 7 {
 8     x=0;
 9     int w=1;
10     char ch=getchar();
11     while(ch<'0'||ch>'9')
12     {
13         if(ch=='-')
14             w=-1;
15         ch=getchar();
16     }
17     while(ch>='0'&&ch<='9')
18     {
19         x=(x<<3)+(x<<1)+ch-'0';
20         ch=getchar();
21     }
22     x*=w;
23 }
24 void input()
25 {
26     freopen("input.txt","r",stdin);
27     //freopen("output.txt","w",stdout);
28 }
29 int main()
30 {
31     //input();
32     while(scanf("%d",&l)==1&&l)
33     {
34         printf("The minimum cutting is ");
35         memset(f,0x3f,sizeof(f));
36         red(n);
37         for(int i=1;i<=n;++i)
38         {
39             red(a[i]);
40             f[i][i+1]=0;
41         }
42         a[n+1]=l;
43         f[0][1]=0;
44         for(int i=2;i<=n+1;++i)
45             for(int j=0;j+i<=n+1;++j)
46             {
47                 int e=j+i;
48                 for(int k=j+1;k<e;++k)
49                     f[j][e]=min(f[j][e],f[j][k]+f[k][e]);
50                 f[j][e]+=a[e]-a[j];
51             }
52         printf("%d.
",f[0][n+1]);
53     }
54     return 0;
55 }
View Code
原文地址:https://www.cnblogs.com/Achensy/p/10845514.html