问题 :给定一个段长为n英寸的钢条和一个价格表pi(i = 1,2,....,n),求钢条切割方案,使收益最大。
先看代码,再解释
#include <bits/stdc++.h>
using namespace std;
//递归
int cutrod(int *price,int n)
{
if(n <= 0)
return 0;
int max_val = INT_MIN;
for(int i = 0; i < n; i++)
{
max_val = max(max_val,price[i]+cutrod(price,n-i-1));
}
return max_val;
}
int main(void)
{
int price[] = {1,5,8,9,10,17,17,20};
int n = sizeof(price)/sizeof(price[0]);
cout << cutrod(price,n);
//重叠子问题
int res[n+1];
res[0] = 0;
for(int i = 1; i <=n; i++)
{
int max_val = INT_MIN;
for(int j = 0; j < i; j++)
{
max_val = max(max_val,price[j]+res[i-j-1]);
}
res[i]= max_val;
}
cout << res[n];
return 0;
}
第一种方法是递归求解,满足最优子结构性质,自顶向下求解。
第二种方法是重叠子问题。
长度 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
price | 1 | 5 | 8 | 9 | 10 | 17 | 17 | 20 |
res数组
长度|索引 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
最大收益 | 0 | 1 | 5 | 8 | 10 | 13 | 17 | 18 | 22 |
长度n=1 | 收益price[0]+res[0] |
n = 2 | max((price[0]+res[1]),price[1]+res[0]) |
n = 3 | max((price[0]+res[2]),price[1]+res[1],price[2]+res[0]) |
........
res数组中的值都是此长度所能分割的最大收益。