Uva 10003 Cutting Sticks (类似于最优矩阵连乘的dp)

题意:有一根长度为L的木棍,和n个切割点的位置(按照从小到大排序),你的任务是在这些切割点的位置把棍子切成n+1份,使得总切割费用最小。每次切割的费用等于被切的木棍长度

思路:这道题与最优矩阵连乘的思想一样,那就是分析最优子结构,再根据子结构来定义状态,首先我们假定第一次分割的最优方案是在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 <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#define INF 0x3f3f3f3f

using namespace std;
int d[55][55];
int cut[55];
bool visit[55][55];
int L,n;

int dp(int i,int j)
{
    if((j-i)<=1) return 0;
    if(visit[i][j]==true) return d[i][j];
    visit[i][j]=true;
    for(int k=i+1;k<j;k++)
        d[i][j]=min(d[i][j],dp(i,k)+dp(k,j)+(cut[j]-cut[i]));
    return d[i][j];
}

int main(int argc, char const *argv[])
{
    while(cin>>L&&L)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&cut[i]);
        }
        cut[0]=0;
        cut[n+1]=L;
        memset(visit,false,sizeof(visit));
        memset(d,INF,sizeof(d));
        int ans=dp(0,n+1);
        cout<<"The minimum cutting is "<<ans<<"."<<endl;
    }
    return 0;
}
时间: 2024-12-14 18:49:08

Uva 10003 Cutting Sticks (类似于最优矩阵连乘的dp)的相关文章

UVA 10003 Cutting Sticks 区间DP+记忆化搜索

UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的长度L,第二行是切割点的个数n,接下来的n行是切割点在木棍上的坐标. 输出切割木棍的最小费用 前话-区间dp简单入门 区间dp的入门下面博客写的非常好,我就是看的他们博客学会的,入门简单,以后的应用就得靠自己了. https://blog.csdn.net/qq_41661809/article/d

uva 10003 Cutting Sticks 简单区间dp

// uva 10003 Cutting Sticks 区间dp // 经典的区间dp // dp(i,j)表示切割小木棍i-j所需要的最小花费 // 则状态转移为dp(i,j) = min{dp(i,k) + dp(k,j) + a[j]-a[i]) // 其中k>i && k<j // a[j] - a[i] 为第一刀切割的代价 // a[0] = 0,a[n+1] = L; // dp数组初始化的时候dp[i][i+1]的值为 0,这表示 // 每一段都已经是切割了的,不

uva 10003 Cutting Sticks (DP)

uva 10003 Cutting Sticks Description 你的任务是替一家叫Analog Cutting Machinery (ACM)的公司切割木棍.切割木棍的成本是根据木棍的长度而定.而且切割木棍的时候每次只切一段.很显然的,不同切割的顺序会有不同的成本.例如:有一根长10公尺的木棍必须在第2.4.7公尺的地方切割.这个时候就有几种选择了.你可以选择先切2公尺的地方,然后切4公尺的地方,最后切7公尺的地方.这样的选择其成本为:10+8+6=24.因为第一次切时木棍长10公尺,

UVA 10003 Cutting Sticks(区间dp)

Description  Cutting Sticks  You have to cut a wood stick into pieces. The most affordable company, The Analog Cutting Machinery, Inc. (ACM), charges money according to the length of the stick being cut. Their procedure of work requires that they onl

uva 10003 Cutting Sticks 【区间dp】

题目:uva 10003 Cutting Sticks 题意:给出一根长度 l 的木棍,要截断从某些点,然后截断的花费是当前木棍的长度,求总的最小花费? 分析:典型的区间dp,其实和石子归并是一样的,花费就是石子的和,那么久不用多说了. AC代码: #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include <map> #include <

UVA 10003 - Cutting Sticks

#include<iostream> #include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; in

uva 10003 Cutting Sticks 切木条dp

这道题有些类似矩阵连乘,就是区间的问题.设dp[i][j]表示从i到j的最小花费,那么dp[i][j]=min{dp[i] [k]+dp[k][j]+a[j]-[i]}(i<k<j)其中a[j]-a[i]表示从i到j的长度,即要切这块木条所需的花费.求大区 间得时候小区间已经算出来了,所以符合动态规划的自底向上,而且是最优子结构,这道题我把0和木条长度加到了a 数组里面,就是说一共有n+2个点,每两个相邻的点不用切割,初始化为1 代码: #include<iostream> #in

UVA - 10003 —— Cutting Sticks

很基础的一道区间DP :) #include <cstdio> #include <iostream> #define INF 0x3f3f3f3f using namespace std; int c[1005]; int dp[1005][1005]; int main () { int l, n; while(scanf("%d", &l)!=EOF && l) { scanf("%d", &n); fo

UVA - 10003 Cutting Sticks(动态规划)

#include<iostream> #include<cstring> using namespace std; const int maxn = 50 + 3; int l, n; int c[maxn]; int dp[maxn][maxn]; int vis[maxn][maxn]; int solve2(int i, int j) { if(i == j - 1) return 0; if(vis[i][j]) return dp[i][j]; vis[i][j] = 1