zoukankan      html  css  js  c++  java
  • UVA 10003 Cutting Sticks

    题意:在给出的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代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int SIZEN=55;
     6 const int INF=1<<30;
     7 int x[SIZEN];
     8 int dp[SIZEN][SIZEN];
     9 int w[SIZEN][SIZEN];
    10 void init()
    11 {
    12     memset(dp,-1,sizeof(dp));
    13 }
    14 int dfs(int l,int r)
    15 {
    16     if(dp[l][r]!=-1) 
    17         return dp[l][r];
    18     int ans=INF;
    19     for(int i=l+1; i<r; i++)
    20     {
    21         ans=min(ans,dfs(l,i)+dfs(i,r));
    22     }
    23     dp[l][r]=ans+w[l][r];
    24     return dp[l][r];
    25 }
    26 void solve(int len)
    27 {
    28     int n;
    29     scanf("%d",&n);
    30     init();
    31     for(int i=1; i<=n; i++) 
    32         scanf("%d",&x[i]);
    33     x[0]=0;
    34     x[n+1]=len;
    35     for(int i=0; i<=n; i++)
    36         for(int j=i; j<=n+1; j++)
    37             w[i][j]=x[j]-x[i];
    38     for(int i=0; i<=n; i++) 
    39         dp[i][i+1]=0;
    40     int ans=dfs(0,n+1);
    41     printf("The minimum cutting is %d.
    ",ans);
    42 }
    43 int main()
    44 {
    45     int len;
    46     while(scanf("%d",&len)!=EOF&&len)
    47         solve(len);
    48 }

    这道题涉及到一个知识点:区间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; 
    这个结构必须记好,这是区间动态规划的代码结构。

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

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int SIZEN=55;
     6 const int INF=1<<30;
     7 int x[SIZEN];
     8 int dp[SIZEN][SIZEN];
     9 int w[SIZEN][SIZEN];
    10 int s[SIZEN][SIZEN];
    11 //dp[i][j]=min(dp[i][k]+dp[k][j])+w[i][j]
    12 void init(){
    13     memset(dp,-1,sizeof(dp));
    14 }
    15 void work(int n){
    16     for(int i=0;i<=n;i++) dp[i][i+1]=0;
    17     for(int i=0;i<=n;i++) s[i][i+1]=i;
    18     for(int l=3;l<=n+2;l++){
    19         for(int i=0;i+l-1<=n+1;i++){
    20             int j=i+l-1;
    21             dp[i][j]=INF;
    22             for(int k=s[i][j-1];k<=s[i+1][j];k++){
    23                 int tmp=dp[i][k]+dp[k][j];
    24                 if(dp[i][j]>tmp){
    25                     dp[i][j]=tmp;
    26                     s[i][j]=k;
    27                 }
    28             }
    29             dp[i][j]+=w[i][j];
    30         }
    31     }
    32 }
    33 void solve(int len){
    34     int n;
    35     scanf("%d",&n);
    36     for(int i=1;i<=n;i++) scanf("%d",&x[i]);
    37     x[0]=0;x[n+1]=len;
    38     for(int i=0;i<=n;i++)
    39         for(int j=i;j<=n+1;j++)
    40         w[i][j]=x[j]-x[i];
    41     work(n);
    42     /*for(int i=0;i<=n+1;i++){
    43         for(int j=i+1;j<=n+1;j++) printf("%d ",dp[i][j]);
    44         printf("
    ");
    45     }
    46     for(int i=0;i<=n+1;i++){
    47         for(int j=i+1;j<=n+1;j++)
    48             printf("%d ",s[i][j]);
    49         printf("
    ");
    50     }*/
    51     printf("The minimum cutting is %d.
    ",dp[0][n+1]);
    52 }
    53 int main()
    54 {
    55     int len;
    56     while(scanf("%d",&len)!=EOF&&len)
    57         solve(len);
    58 }

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

    ————Anonymous.PJQ
  • 相关阅读:
    利用CSS3 中steps()制用动画
    移动WEB测试工具 Adobe Edge Inspect
    Grunt配置文件编写技巧及示范
    CSS3 box-shadow快速教程
    编写爬虫程序的神器
    node+express+jade搭建一个简单的"网站"
    node+express+ejs搭建一个简单的"页面"
    node的模块管理
    node的调试
    mongoDB的权限管理
  • 原文地址:https://www.cnblogs.com/PJQOOO/p/3898552.html
Copyright © 2011-2022 走看看