uva 10003 Cutting Sticks (动态规划:区间DP)

来源:互联网 发布:javascript 遍历json 编辑:程序博客网 时间:2024/05/29 10:56

题意是根据从一个木棍中间截取不同长度,求出最小花费

对于一根长为len的木棍,从x处截断,则花费len,并把当前木棍截为(x,len-x)两段

类似于矩阵连乘,根据很巧妙,自己没有想到

用记忆化搜索的方法就很好写

dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j]+a[j]-a[i])

//dp[i][j]表示对当前左端为a[i],右端为a[j]的木棍截取所需最小花费

代码如下:

#include <cstdio>#include <cstring>#include <algorithm>#define MAXN 1010#define INF 0x3f3f3f3fusing namespace std;int a[MAXN];int dp[MAXN][MAXN];int dfs(int i, int j) {    if(dp[i][j] != -1)        return dp[i][j];    if(i+1 == j)        return dp[i][j] = 0;    dp[i][j] = INF;    int tmp;    for(int k=i+1; k<j; ++k) {        tmp = dfs(i, k)+dfs(k, j)+a[j]-a[i];        dp[i][j] = min(dp[i][j], tmp);    }    return dp[i][j];}int main(void) {    int n, len;    while(scanf("%d", &len) && len) {        scanf("%d", &n);        a[0] = 0;        a[n+1] = len;        for(int i=1; i<=n; ++i)            scanf("%d", &a[i]);        memset(dp, -1, sizeof(dp));        printf("The minimum cutting is %d.\n", dfs(0, n+1));    }    return 0;}


0 0