题意:在给出的n个结点处切断木棍,并且在切断木棍时木棍有多长就花费多长的代价,将所有结点切断,并且使代价最小。

思路:设DP[i][j]为,从i,j点切开的木材,完成切割需要的cost,显然对于所有DP[i][i+1]=0,记w[i][j]为从i,j点切开的木材的长度,因此可以枚举切割点,dp[i][j]=min(dp[i][k]+dp[k][j])+w[i][j],k就是枚举的切割点.

AC代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int SIZEN=;
const int INF=<<;
int x[SIZEN];
int dp[SIZEN][SIZEN];
int w[SIZEN][SIZEN];
void init()
{
memset(dp,-,sizeof(dp));
}
int dfs(int l,int r)
{
if(dp[l][r]!=-)
return dp[l][r];
int ans=INF;
for(int i=l+; i<r; i++)
{
ans=min(ans,dfs(l,i)+dfs(i,r));
}
dp[l][r]=ans+w[l][r];
return dp[l][r];
}
void solve(int len)
{
int n;
scanf("%d",&n);
init();
for(int i=; i<=n; i++)
scanf("%d",&x[i]);
x[]=;
x[n+]=len;
for(int i=; i<=n; i++)
for(int j=i; j<=n+; j++)
w[i][j]=x[j]-x[i];
for(int i=; i<=n; i++)
dp[i][i+]=;
int ans=dfs(,n+);
printf("The minimum cutting is %d.\n",ans);
}
int main()
{
int len;
while(scanf("%d",&len)!=EOF&&len)
solve(len);
}

这道题涉及到一个知识点:区间DP:(转自calmound)

区间动态规划问题一般都是考虑,对于每段区间,他们的最优值都是由几段更小区间的最优值得到,是分治思想的一种应用,将一个区间问题不断划分为更小的区间直至一个元素组成的区间,枚举他们的组合 ,求合并后的最优值。
设F[i,j](1<=i<=j<=n)表示区间[i,j]内的数字相加的最小代价
最小区间F[i,i]=0(一个数字无法合并,∴代价为0)

每次用变量k(i<=k<=j-1)将区间分为[i,k]和[k+1,j]两段
For p:=1 to n do // p是区间长度,作为阶段。 
for i:=1 to n do // i是穷举的区间的起点
begin
j:=i+p-1; // j是 区间的终点,这样所有的区间就穷举完毕
if j>n then break; // 这个if很关键。
for k:= i to j-1 do // 状态转移,去推出 f[i,j]
f[i , j]= max{f[ i,k]+ f[k+1,j]+ w[i,j] } 
end; 
这个结构必须记好,这是区间动态规划的代码结构。

下面是关于该题的一个优化代码(四边形优化),我还没搞懂,先贴出来吧:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int SIZEN=;
const int INF=<<;
int x[SIZEN];
int dp[SIZEN][SIZEN];
int w[SIZEN][SIZEN];
int s[SIZEN][SIZEN];
//dp[i][j]=min(dp[i][k]+dp[k][j])+w[i][j]
void init(){
memset(dp,-,sizeof(dp));
}
void work(int n){
for(int i=;i<=n;i++) dp[i][i+]=;
for(int i=;i<=n;i++) s[i][i+]=i;
for(int l=;l<=n+;l++){
for(int i=;i+l-<=n+;i++){
int j=i+l-;
dp[i][j]=INF;
for(int k=s[i][j-];k<=s[i+][j];k++){
int tmp=dp[i][k]+dp[k][j];
if(dp[i][j]>tmp){
dp[i][j]=tmp;
s[i][j]=k;
}
}
dp[i][j]+=w[i][j];
}
}
}
void solve(int len){
int n;
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&x[i]);
x[]=;x[n+]=len;
for(int i=;i<=n;i++)
for(int j=i;j<=n+;j++)
w[i][j]=x[j]-x[i];
work(n);
/*for(int i=0;i<=n+1;i++){
for(int j=i+1;j<=n+1;j++) printf("%d ",dp[i][j]);
printf("\n");
}
for(int i=0;i<=n+1;i++){
for(int j=i+1;j<=n+1;j++)
printf("%d ",s[i][j]);
printf("\n");
}*/
printf("The minimum cutting is %d.\n",dp[][n+]);
}
int main()
{
int len;
while(scanf("%d",&len)!=EOF&&len)
solve(len);
}

本篇博文并非出自本人之手,只是做个总结,感谢ACalvin男神的帮助。

UVA 10003 Cutting Sticks的更多相关文章

  1. uva 10003 Cutting Sticks 【区间dp】

    题目:uva 10003 Cutting Sticks 题意:给出一根长度 l 的木棍,要截断从某些点,然后截断的花费是当前木棍的长度,求总的最小花费? 分析:典型的区间dp,事实上和石子归并是一样的 ...

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

    UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的 ...

  3. uva 10003 Cutting Sticks(区间DP)

    题目连接:10003 - Cutting Sticks 题目大意:给出一个长l的木棍, 再给出n个要求切割的点,每次切割的代价是当前木棍的长度, 现在要求输出最小代价. 解题思路:区间DP, 每次查找 ...

  4. UVA 10003 Cutting Sticks(区间dp)

    Description    Cutting Sticks  You have to cut a wood stick into pieces. The most affordable company ...

  5. UVa 10003 - Cutting Sticks(区间DP)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  6. UVA 10003 Cutting Sticks 切木棍 dp

    题意:把一根木棍按给定的n个点切下去,每次切的花费为切的那段木棍的长度,求最小花费. 这题出在dp入门这边,但是我看完题后有强烈的既是感,这不是以前做过的石子合并的题目变形吗? 题目其实就是把n+1根 ...

  7. UVA - 10003 Cutting Sticks(切木棍)(dp)

    题意:有一根长度为L(L<1000)的棍子,还有n(n < 50)个切割点的位置(按照从小到大排列).你的任务是在这些切割点的位置处把棍子切成n+1部分,使得总切割费用最小.每次切割的费用 ...

  8. uva 10003 Cutting Sticks (区间dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接:  打开 题目大意 一根长为l的木棍,上面有n个"切点",每个点的位置为c[i] 要按照一 ...

  9. 10003 Cutting Sticks(区间dp)

      Cutting Sticks  You have to cut a wood stick into pieces. The most affordable company, The Analog ...

随机推荐

  1. VS2013 Qt5 Mysql中文编码问题

    Qt开始默认是utf-8,而VS2013默认程序编码为gb2312: 这样就会发现使用中文的时候乱码. 一般有二种解决方案: 1.在使用中文的时候,使用QTextCodec QTextCodec *g ...

  2. 网站实战 从效果图开始CSS+DIV 布局华为网站

    经过我们的前面css的学习,我们已经分模块的掌握的CSS的技术,但是,要是完整的做一个页面,我们还没有接触过,这次呢,小强老师来和大家完整的利用CSS+DIV做一个网站案例,我们来模仿下华为的网站. ...

  3. uva 10313 Pay the Price(完全背包)

    题目连接:10313 - Pay the Price 题目大意:有0~300这300种价值的金额. 现在可能给出参数: 1个:n, 输出可以组成价值n的方式的个数. 2个:n, a输出用个数小于a的价 ...

  4. Struts2 学习笔记17 I18N国际化

    讲解一下国际化的内容,比如书有些大的网站可以一键切换语言,例如中英切换,这时候就会用到国际化.但是由于struts2大多数是用来写后台,国际化并不是十分重要,而且用国际化开发会减慢开发的速度,大家只要 ...

  5. PHP脚本监控程序

    #!/bin/sh # Find ip IP=`/sbin/ifconfig eth1 | grep 'inet addr' | awk '{ print substr($2, index($2, & ...

  6. Java8 Lamdba表达式 001

    在一个已经存在的编程语言里非常少有对现有的生态系统起重大影响的新特性.Lambda表达式对于Java语言就是这样的意义的存在.简单来说,Lambda表达式提供了便利的方式去创建一个匿名的功能.提供了一 ...

  7. [置顶] 【玩转cocos2d-x之三十】点九图和输入框的使用

    原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/17297721 登录界面一个帐号/密码输入框或者主角命名框是少不了的.这节就来 ...

  8. NSUserDefaults设置bool值重新启动后bool仅仅设置丢失问题

    今天使用NSUserDefaults保存bool至重新启动后发现bool值没有保存对 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults ...

  9. CloudStack 4.2 新功能:集成SNMP进行系统监控(原理篇)

    作者微博:http://weibo.com/tianchunfeng CloudStack 4.2 版本发布在即,相信不久后对 4.2 版本新功能(共有13个)的介绍会逐渐多起来.因为无论是从架构底层 ...

  10. oracle执行带输入输入参数的存储过程

    declare a1 ); a2 ); begin PKG_INPATIENT.prc_autojf('Y', a1, a2); end;