UVA10003---Cutting Sticks(简单区间dp)

任意两个切割点之间无法再分割

所以如果设dp[i][j] 表示从i位置切到j位置其实没有多大意义,亲测这样会TLE

dp[i][j]表示切割第i个切割点开始的位置到第j个切割点的位置结束的木棍的最小花费

时间复杂度O(n3)

/*************************************************************************
    > File Name: uva10003.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年05月21日 星期四 21时21分07秒
 ************************************************************************/

#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>

using namespace std;

const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

int dp[55][55];
int pos[55];

int main() {
    int n, l;
    while (~scanf("%d", &l), l) {
        memset(dp, inf, sizeof(dp));
        scanf("%d", &n);
        pos[0] = 0;
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &pos[i]);
            dp[i - 1][i] = 0;
        }
        pos[n + 1] = l;
        dp[n][n + 1] = 0;
        for (int i = n; i >= 0; --i) {
            for (int j = i + 1; j <= n + 1; ++j) {
                for (int k = i; k <= j; ++k) {
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + pos[j] - pos[i]);
                }
            }
        }
        printf("The minimum cutting is %d.\n", dp[0][n + 1]);
    }
}
时间: 2024-11-06 16:42:27

UVA10003---Cutting Sticks(简单区间dp)的相关文章

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)

题目大意:将一段长为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 name

uva 10003 Cutting Sticks 【区间dp】

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

uva10003 - Cutting Sticks(简单动规)

/* * Author: Bingo * Created Time: 2015/2/13 18:33:03 * File Name: uva10003.cpp */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string>

UVa10003 Cutting Sticks

考虑d(i,j)表示切割点i到j这段距离的最小花费,于是d(i,j)=min(d(i,k)+d(k,j))+a[j]-a[i] ,其中j<k<i,边界条件d(i,i)=d(i,i+1)=0,最终求d(0,n+1),复杂度o(n^3),可采用记忆化搜索. /*----UVa10003 Cutting Sticks 设d(i,j)为切割木棍(i,j)的最小费用,则d(i,j)=a[j]-a[i]+min{d(i,k)+d(k,j)} i<k<=j;最终求d(0,n+1) 为了方便,可以

poj2955 Brackets 简单区间dp

// poj2955 简单区间dp // d[i][j]表示i到j区间所能形成的最大匹配序列 // dp[i][j] = max(dp[i][k]+dp[k+1][j]){i<k<j} // dp[i][j] = max(dp[i+1][j-1]+2) if (s[i] match s[j]) // // 记忆化搜索的时候,将dp[i][i] = 0 ,其他赋值成-1; // // 做题的时候刚开始将dp[i][j]弄成0了,结果一直tle // 最后发现有好多的状态重复计算了,所以会tle

简单Dp----最长公共子序列,DAG最长路,简单区间DP等

/* uva 111 * 题意: * 顺序有变化的最长公共子序列: * 模板: */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[100]; int mu[100]; int Dp[100][100]; int main() { int n,x; scanf("%d", &n

Uva 10003-Cutting Sticks(区间DP)

题目链接:点击打开链接 题意: 一根长度为L 的木棒,要求要切割n次,给出n次需要切割的位置,每次切割花费为当前段的总长度.求最小花费. 思路:..一开始想了好久也没往区间DP那方面想QAQ.设 dp[i][j] 为切割[i,j] 区间的最小花费,状态转移方程为 dp[i][j]=max(dp[i][k-1]+dp[k+1][j]+a[j+1]-a[i-1]); #include <algorithm> #include <iostream> #include <cstrin

POJ 3186 Treats for the Cows (简单区间DP)

FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for giving vast amounts of milk. FJ sells one treat per day and wants to maximize the money he receives over a given period time. The treats are interesting for many reasons