题面
题意
思路
明显,对小棒ij中间k点来一刀,小棒就变成了ik,jk两个小棒,并且花费为j-i,很容易想到区间dp,用
d
[
i
]
[
j
]
d[i][j]
d[i][j]表示把小棒ij分到不能分为止最小的花费,那么得到状态转移方程:
d
[
i
]
[
j
]
=
m
i
n
(
d
[
i
]
[
j
]
,
d
[
i
]
[
k
]
+
d
[
j
]
[
k
]
+
j
−
i
)
d[i][j]=min(d[i][j],d[i][k]+d[j][k]+j-i)
d[i][j]=min(d[i][j],d[i][k]+d[j][k]+j−i)
所求的结果为
d
[
0
]
[
L
]
d[0][L]
d[0][L]
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 55;
const int maxl = 1100;
const int inf = 0x3f3f3f3f;
int cut[maxn];
int d[maxl][maxl];
int main()
{
int L;
int n;
int Case=0;
while (cin >> L )
{
if(L==0) break;
else cin>>n;
Case++;
memset(d, inf, sizeof(d));
for (int i = 1; i <= n; i++)
cin >> cut[i];
cut[0] = 0;
cut[n + 1] = L;
for (int i = 2; i <= n; i++)
{
d[cut[i - 1]][cut[i]] = 0;
}
d[0][cut[1]] = 0;//这一块
d[cut[n]][L] =0;//很细节
cut[0] = 0;//可以多想想
cut[n + 1] = L;//为什么这样搞
for (int l = 3; l <= n+2; l++)
{
for (int i = 0; i <= n + 2 - l; i++)
{
for (int k = i + 1; k <= i + l - 2; k++)
{
d[cut[i]][cut[i + l - 1]] = min(d[cut[i]][cut[i + l - 1]], d[cut[i]][cut[k]] + d[cut[k]][cut[i + l - 1]] + cut[i + l - 1] - cut[i]);
}
}
}
cout<<"The minimum cutting is "<<d[0][L]<<"."<<endl;
}
return 0;
}