Cutting Sticks |
It is easy to notice that different selections in the order of cutting can led to different prices. For example, consider a stick of length 10 meters that has to be cut at 2, 4 and 7 meters from one end. There are several choices. One can be cutting first at 2, then at 4, then at 7. This leads to a price of 10 + 8 + 6 = 24 because the first stick was of 10 meters, the resulting of 8 and the last one of 6. Another choice could be cutting at 4, then at 2, then at 7. This would lead to a price of 10 + 4 + 6 = 20, which is a better price.
Your boss trusts your computer abilities to find out the minimum cost for cutting a given stick.
The next line consists of n positive numbers ci ( 0 < ci < l) representing the places where the cuts have to be done, given in strictly increasing order.
An input case with l = 0 will represent the end of the input.
100 3 25 50 75 10 4 4 5 7 8 0
The minimum cutting is 200. The minimum cutting is 22.
---------------------------------------
区间dp的经典题目?。。。。。
f[i][j]表示切割区间i-j的最小费用。
枚举k,f[i][j]=min(f[i][k]+f[k][j]+a[j]-a[i]);(i<k<j);
从今天开始练短码
---------------------------------------
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int OO=1e9; int f[111][111]; int a[111]; int n; int l; int dfs(int l,int r) { int ret=OO; if (f[l][r]!=-1) return f[l][r]; if (l==r) return f[l][r]=0; if (l+1==r) return f[l][r]=0; for (int k=l+1;k<=r-1;k++) ret=min( ret, dfs(l,k)+dfs(k,r)+a[r]-a[l] ); return f[l][r]=ret; } int main() { while (~scanf("%d",&l)) { if (l==0) break; memset(a,0,sizeof(a)); memset(f,-1,sizeof(f)); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); a[0]=0; a[n+1]=l; int ans=dfs(0,n+1); printf("The minimum cutting is %d.\n",ans); } return 0; }