UVA - 10003 Cutting Sticks - (DP)

题目链接:https://cn.vjudge.net/problem/UVA-10003

题意:给出一根长为L的木棍,给出长为n的c数组,c[i]代表在木棍的长为c[i]处为一个切割点,每次切割的木棍的长度为花费,让选择切点的顺序,使得费用最小。

很好的dp题,题解来自:https://www.cnblogs.com/simplekinght/p/6953258.html

思路:这道题与最优矩阵连乘的思想一样,那就是分析最优子结构,再根据子结构来定义状态,首先我们假定第一次分割的最优方案是在k处分割,得到0~k与k~L两段木棍,那么如何最优分割0~k与0~L就是它的子问题,我们根据子问题定义状态d(i,j)是分割从割点i到割点j的最优方案,状态转移方程 d(i,j)=min{d(i,k)+d(k,j)+(cut[j]-cut[i])}(其中i<k<j),接下来是确定边界,d(i,i)=0 和 d(i,i+1)=0,并注意赋初值INF

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxN=55;
const ll INF=0x7f;

int L,n,c[maxN],ans;
int dp[maxN][maxN];//dp(i,j)是分割从割点i到割点j的最优方案
bool vis[maxN][maxN];

int fdp(int i,int j)
{
    if((j-i)<=1) return 0;
    if(vis[i][j]==true) return dp[i][j];

    vis[i][j]=true;
    for(int k=i+1;k<j;k++)
        dp[i][j]=min(dp[i][j],fdp(i,k)+fdp(k,j)+(c[j]-c[i]));
    return dp[i][j];
}

int main()
{
    while(scanf("%d",&L)&&L)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&c[i]);
        c[0]=0;c[n+1]=L;
        memset(dp,0x7f,sizeof(dp));
        memset(vis,0,sizeof(vis));
        printf("The minimum cutting is %d.\n",fdp(0,n+1));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值