题意:在给出的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. 【转载】django在eclipse环境下建web网站

    一.创建一个项目如果这是你第一次使用Django,那么你必须进行一些初始设置.也就是通过自动生成代码来建立一个Django项目--一个Django项目的设置集,包含了数据库配置.Django详细选项设 ...

  2. Qt新建线程的方法(有QRunnable,QThreadPool,moveToThread和QtConcurrent的例子)

    看了不少Qt线程的东西,下面总结一下Qt新建一个线程的方法. 一.继承QThread 继承QThread,这应该是最常用的方法了.我们可以通过重写虚函数void QThread::run ()实现我们 ...

  3. ubuntu 12.04 安装sublime2

    add-apt-repository ppa:webupd8team/sublime-text-2 apt-get update apt-get install sublime-text 安装控制器: ...

  4. Swift - 禁用UIWebView和WKWebView的下拉拖动效果

    使用UIWebView或WKWebView加载网页时,如果页面处于最顶端时,用户用手指往下拖动,会露出灰色空背景.同样页面在最底部的时候,继续向上拖动,下方也会露出空背景. 要禁止这个拖动效果,可进行 ...

  5. JavaScript实现获取table中某一列的值

    JavaScript实现获取table中某一列的值 1.实现源代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional/ ...

  6. Python 3语法小记(四)字典 dictionary

    字典是Python里面一种无序存储结构,存储的是键值对 key - value.关键字应该为不可变类型,如字符串.整数.包含不可变对象的元组. 字典的创建很简单,用 d = {key1 : value ...

  7. transition与animation

    以前,一直都知道,transition是animation的一个简化版,甚至不算是动画,而是一种过渡. transition的用法 早两天用transition写了一个按钮滑动的效果,类似于IOS的设 ...

  8. ARMv8 Linux内核head.S源码分析

    ARMv8Linux内核head.S主要工作内容: 1. 从el2特权级退回到el1 2. 确认处理器类型 3. 计算内核镜像的起始物理地址及物理地址与虚拟地址之间的偏移 4. 验证设备树的地址是否有 ...

  9. 无限层级且乱序的树形结构数据的整理,利用HashMap降低遍历次数

    我们在展示一个机构树的时候,经常会遇到这种一个问题,查询数据的时候,是从下往上查的,但展示数据的时候,又要从下往上展示. 这时候就要把查询到的数据进行整理从而得到我们想要的结构. 举个样例. ID P ...

  10. Android SurfaceView实现静态于动态画图效果

    本文是基于Android的SurfaceView的动态画图效果,实现静态和动态下的正弦波画图,可作为自己做图的简单参考,废话不多说,先上图, 静态效果: 动态效果: 比较简单,代码注释的也比较详细,易 ...