UVA 10003 Cutting Sticks(区间dp)

来源:互联网 发布:oppoa209软件下载 编辑:程序博客网 时间:2024/05/16 06:48

题目链接:UVA - 10003 Cutting Sticks

题意

给一长度为L的棍子,和n个切割点,每次切割的代价为当前的棍子的长度,问最少的总切割代价是多少。

思路

典型的区间dp
dp[i][j] = min(dp[i][k]+dp[k][j]+a[j]-a[i]) |i

代码

递推

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <cstdlib>#include <vector>#include <cmath>using namespace std;const int N = 59;int a[N];int dp[N][N];int main(){    int l;    while(~scanf("%d", &l) && l)    {        int n;        memset(dp, 0x3f, sizeof(dp));        scanf("%d", &n);        for(int i=1; i<=n; i++)        {            dp[i-1][i] = 0;            scanf("%d", &a[i]);        }        dp[n][n+1] = 0;        a[0] = 0;        a[n+1] = l;        for(int len=2; len<=n+1; len++)            for(int i=0; i+len<=n+1; i++)                for(int k=i+1; k<i+len; k++)                    dp[i][i+len] = min(dp[i][i+len], dp[i][k]+dp[k][i+len]+a[i+len]-a[i]);        printf("The minimum cutting is %d.\n", dp[0][n+1]);    }    return 0;}

记忆化搜索

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <cstdlib>#include <vector>#include <cmath>using namespace std;const int N = 59;int a[N];int dp[N][N];int dfs(int i, int j){    if(dp[i][j] != -1)        return dp[i][j];    int ans = 0x3f3f3f3f;    for(int k=i+1; k<j; k++)        ans = min(ans, dfs(i,k)+dfs(k,j)+a[j]-a[i]);    return dp[i][j] = ans;}int main(){    int l;    while(~scanf("%d", &l) && l)    {        int n;        memset(dp, -1, sizeof(dp));        scanf("%d", &n);        for(int i=1; i<=n; i++)        {            scanf("%d", &a[i]);            dp[i-1][i] = 0;        }        dp[n][n+1] = 0;        a[0] = 0;        a[n+1] = l;        printf("The minimum cutting is %d.\n", dfs(0, n+1));    }    return 0;}
0 0
原创粉丝点击