UVA-10003 Cutting Sticks (区间DP)

题目大意:将一段长为L的木棒在给定的n个切割点切开,每切一次的花费等于当前木棒的长度。求切成n+1段的最小花费。

题目分析:区间DP。定义dp(i,j)表示切割区间i~j的花费,则 f(i,j)=min(f(i,k)+f(k,j))+dist(i,j)。时间复杂度为n3

代码如下:

# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;
const int INF=100000000;
int a[55],dp[55][55],n;
void DP()
{
    for(int l=0;l<=n+1;++l){
        for(int i=0;i+l<=n+1;++i){
            int r=i+l;
            dp[i][r]=INF;
            if(l==0)///l为0说明现在是第一刀。
                dp[i][r]=a[n+1]-a[0];
            if(l==1)///l为1说明现在不用切割。
                dp[i][r]=0;
            for(int k=i+1;k<r;++k)
                dp[i][r]=min(dp[i][r],dp[i][k]+dp[k][r]+a[r]-a[i]);
        }
    }
}
int main()
{
    int l;
    while(scanf("%d",&l)&&l)
    {
        scanf("%d",&n);
        a[0]=0;
        for(int i=1;i<=n;++i)
            scanf("%d",a+i);
        a[n+1]=l;
        sort(a,a+n+2);
        DP();
        printf("The minimum cutting is %d.\n",dp[0][n+1]);
    }
    return 0;
}

  

时间: 2024-10-11 01:04:28

UVA-10003 Cutting Sticks (区间DP)的相关文章

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

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

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<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)

题意:有一根长度为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,

10003 - Cutting Sticks(DP)

类似于最优矩阵链乘,将长区间划分成段区间求解,换句话说:长区间依赖于段区间 . 因此如果利用二重循环递推的话,枚举的顺序应该是木棍的长度从小到大,因为长区间依赖于短区间的最优解 . 所以动态规划的重点我认为就是对状态的定义和动态规划的方向,  状态的定义要确保覆盖所有状态,规划的方向要遵循一个状态依赖于另一个早已解决的状态.     所以该题有两种解决方法:记忆化搜索和递推 . 我分别用这两种方法AC了,记忆化搜索更简单易想,耗时0.339.但是递推更快!耗时0.086 .细节请见代码: 1.记