UVA10003固定点切木棍,怎么切使得每次切之前的木棍长度总和最小

这题,刚开始想了很久没有想到怎么处理,其实如果想通了很简单的,

用d[begin][end]表示从bigin切点到end切点,这段木棍的最省钱切法,然后就模拟切中间各点,计算交给递归下一层。。。

没有后效性,记忆化搜索,子问题重叠,这三个是dp题目的基本要素。

此题,刚好是一个经典的DP题,当然既可以用递推,也可以用记忆化搜索。

有点像矩阵链乘问题,找到状态转移公式就好了dp[i][j]=max{dp[i][k]+dp[k][j]+len[j]-len[i]|i

递推:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
using namespace std;
const int maxn=1e4+10;
const double eps=1e-6;
int l,num;
int main()
{
    while(cin>>l&&l)
    {
        cin>>num;
        int a[55];
        int dp[55][55];
        for(int i=1;i<=num;i++)
            cin>>a[i];
        a[0]=0;
        a[num+1]=l;
        memset(dp,0,sizeof(dp));
        for(int l=2;l<=num+1;l++)
        {
            for(int i=0;i+l<=num+1;i++)
            {
                int j=i+l;
                dp[i][j]=maxn;
                for(int k=i+1;k
记忆化搜索:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
using namespace std;
const int maxn=1e4+10;
const double eps=1e-6;
int l,n ,a[55],d[55][55];
int dp(int b,int e)
{
    if(d[b][e]>=0)
        return d[b][e];
    d[b][e]=dp(b,b+1)+dp(b+1,e)+a[e]-a[b];
    for(int i=b+2;i>l&&l)
    {
        cin>>n;
        for (int i = 0; i <= n + 1; i++)
           for (int j = 0; j <= n + 1; j++)
               if (j - i == 1)
                    d[i][j] = 0;
               else
                   d[i][j] = -1;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        a[0]=0;
        a[n+1]=l;
        printf("The minimum cutting is %d.\n",dp(0,n+1));
    }
    return 0;
}



你可能感兴趣的:(DP,UVA)