题意:在给出的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. QtSoap调用Web Service(QtSoap是非官方应用)

    今天学习如何用QtSoap访问Web Service服务.这里调用的是查询QQ在线状态的服务qqOnlineWebService.调用的几个步骤: 1.创建QtSoapMessage对象 messag ...

  2. Android_简单笔记一

    入门学习Android的简单笔记(已经安装好了开发环境ADT) 一.关于 AndroidManifest.xml文件 1. android:icon和android:label定义了应用程序安装后显示 ...

  3. Silk Icons —— 再来 700 个免费小图标

    http://mp.weixin.qq.com/mp/appmsg/show?__biz=MjM5NzM0MjcyMQ==&appmsgid=10000977&itemidx=2&am ...

  4. 解决linux下javac -version和java -version版本显示不一致

    解决linux下javac -version和java -version版本显示不一致 [javascript] view plaincopy [root@localhost usr]# $JAVA_ ...

  5. SAP 金税接口介绍

    一.金税发票与SAP系统发票的税额差异分析 1.1 金税系统中的税额说明 国内企业销售产品给国内客户时,正常产品须要缴纳17%的增值税,而金税(Golden Tax)系统就是用来出具纸面的增值税发票的 ...

  6. c语言,volatile

          一.意义: 该关键字的意义就是表示定义的变量值随时都会改变,必须从变量的地址处读取值,所以只有这个变量在使用过程中可能被改变(比如中断程序),就需要用这个关键字说明. )volatile, ...

  7. Java基础05 实施接口

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在封装与接口中,private关键字封装了对象的内部成员.经过封装,产品隐藏了内部 ...

  8. 动态Pivot(1)

    原文 http://book.51cto.com/art/200710/58874.htm 7.7  动态Pivot 作为另外一个练习,假设你要编写一个存储过程,它生成动态Pivot查询.这个存储过程 ...

  9. 基于visual Studio2013解决面试题之1003字符串逆序

     题目

  10. <Win32_12>程序员求爱的创意程序——升级版^_^

    前段时间,我编写了一个创意程序,并用于向自己目前的女朋友表白,结果效果还不错,得到了她的芳心. 于是我将自己的创意程序共享到csdn资源上,大多数网友认为创意不错,就是简单了些——呵呵,其实我个人也这 ...