zoukankan      html  css  js  c++  java
  • UVA 10003 Cutting Sticks 切木棍 dp

    题意:把一根木棍按给定的n个点切下去,每次切的花费为切的那段木棍的长度,求最小花费。

    这题出在dp入门这边,但是我看完题后有强烈的既是感,这不是以前做过的石子合并的题目变形吗?

    题目其实就是把n+1根木棍合并成一只长木棍,花费为合并后的木棍长度。

    于是我很开心地用优先队列敲完代码,wa了。。。

    后来发现两个木棍的序号必须是连续的,用优先队列会把序号打乱。每次删减中间的一个数又很费时间,于是想到用list+递归,就当我得意的敲出代码,过了不少代码时,它继续给我wa了。。。

    我非常郁闷的在board上找样例,发现有几组是过不了的,比如:

    111
    10
    10 17 28 30 37 44 47 49 77 94

    然后我就跪了,单步去调试,发现贪心没写错。

    于是跟基友讨论未果,然后在网上找到了这个:石子合并问题

    看来贪心时可能会对接下去的计算产生影响,所以不一定是最优解。。。

    下面才是正解 TAT:

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

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

    这题让我学到很多东西,我体验了贪心并不是最优解这一惨痛事实,让我更加体会到dp的思想。

    代码:

    /*
    *  Author:      illuz <iilluzen[at]gmail.com>
    *  Blog:        http://blog.csdn.net/hcbbt
    *  File:        _uva10003.cpp
    *  Create Date: 2013-09-20 16:04:57
    *  Descripton:  dp 
    */
    
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 55;
    int s[MAXN], d[MAXN][MAXN], len, n;
    
    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) + s[e] - s[b];
    	for (int i = b + 2; i < e; i++) {
    		int tt = dp(b, i) + dp(i, e) + s[e] - s[b];
    		d[b][e] = min(d[b][e], tt);
    	}
    	return d[b][e];
    }
    
    int main() {
    	while (scanf("%d", &len) && len) {
    		scanf("%d", &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 = 0; i < n; i++)
    			scanf("%d", &s[i + 1]);
    		s[n + 1] = len;
    		printf("The minimum cutting is %d.
    ", dp(0, n + 1));
    	}
    	return 0;
    }


  • 相关阅读:
    安装RabbitMQ说明
    死锁
    管程
    MybatisPlus快速开发
    了解Mybatis-Plus
    查看监听器状态
    The command supports no service 解决办法
    任务11 Arduino光照报警器
    任务10 测试光的强度实验
    任务9 Arduino光敏实验
  • 原文地址:https://www.cnblogs.com/riskyer/p/3331337.html
Copyright © 2011-2022 走看看