题目
题目描述
有一根长度为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。
输入输出格式
输入格式
***
输出格式
***(逃)
输入输出样例
输入样例
1 2 3 4 5 6 7
| 100 3 25 50 75 10 4 4 5 7 8 0
|
输出样例
1 2
| The minimum cutting is 200. The minimum cutting is 22.
|
题解
代表性记忆化搜索,也可区间DP
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include<bits/stdc++.h> using namespace std; const int maxn=50+5; int n,L,a[maxn],vis[maxn][maxn],d[maxn][maxn]; inline int dp(int i, int j) { if(i>=j-1)return 0; if(vis[i][j])return d[i][j]; vis[i][j]=1; register int& ans=d[i][j]; ans=-1; for(register int k(i+1); k<=j-1; ++k) { register int v(dp(i,k)+dp(k,j)+a[j]-a[i]); if(ans<0||v<ans)ans=v; } return ans; } int main(int argc,char **argv) { while(scanf("%d%d",&L,&n)==2&&L) { for(register int i(1); i<=n; ++i)scanf("%d",&a[i]); a[0]=0; a[n+1]=L; memset(vis,0,sizeof(vis)); printf("The minimum cutting is %d.\n",dp(0,n+1)); } return 0; }
|
其它