本题吧,经典的DP。本菜鸟第一次写解题报告,以前的题都没好意思写。求高手别喷。
题目意思应该还是很明白的。就是一根木头,告诉你多长,要切几下,分别切在哪些个点。然后呢,切一根多长的木头,就要多少钱。然后求一个最便宜的切木有的方案。
这个题目是跟白书配套的,看过那个9.4的最优矩阵链乘的话,就能够想到,其实这个题思路跟那个矩阵链乘一样的。
核心的东西就是这个方程:dp(i,j)=min{dp(i,k)+dp(k,j)+c[j]-c[i]}(其中(i<k<j),k也就是切断第i个点跟第j个点之间的那段木头的那个点)
最后稍注意一下边界的条件,当i+1=j的时候,就是已经切到极限的时候,dp(i,j)显然是0。
依样画葫芦吧,用记忆化搜索写了一遍。
View Code
1 #include <iostream>
2 using namespace std;
3 #define MAX 0xffffff
4 int d[60][60],c[60];
5 int dp(int i,int j)
6 {
7 int &ans = d[i][j];
8 if(ans != -1) return ans;
9 else if(i + 1 == j)
10 {
11 ans = 0;
12 return ans;
13 }
14 else
15 {
16 ans = MAX;
17 int temp,k;
18 for(k = i + 1;k < j;k++)
19 {
20 temp = dp(i,k) + dp(k,j) + c[j] - c[i];
21 if(temp < ans) ans = temp;
22 }
23 }
24 return ans;
25 }
26 int main()
27 {
28 int len,points;
29 while(cin>>len)
30 {
31 if(len == 0)
32 break;
33 cin>>points;
34 c[0] = 0;
35 c[points + 1] = len;
36 int i,j;
37 for(i = 1;i <= points;i++)
38 {
39 cin>>c[i];
40 }
41 for(i = 0;i < 60;i++)
42 for(j = 0;j < 60;j++)
43 d[i][j] = -1;
44 int answer = dp(0,points + 1);
45 cout<<"The minimum cutting is "<<answer<<"."<<endl;
46 }
47 return 0;
48 }