zoukankan      html  css  js  c++  java
  • hdu1227 dp

    题意:在一条路上有 n 个站点,并给定了每个站点的坐标,然后想要在 k 个站点旁边分别各建一个补给站,求所有站点到最近的补给站的距离和的最小值。

    是的,毫无疑问,显然是 DP 问题,但是这题怎么递推还是需要考虑的,我一开始是以 dp [ k ] [ i ] 表示设好第 k 个补给站并讨论到第 i 个站点时的最短路径,即第 k 个补给站不一定是设在第 i 个站点的,但是敲了一半我就发现这样做非常麻烦,因为首先我必须记录下每次 dp 时最后一个站点的位置,其次我还要对于每个考虑到的站点分析最后一个补给站设在之前(即从 dp [ k ] [ i - 1 ]转移)或在第 i 站(即从 dp [ k - 1 ] [ i - 1 ]转移并修改中间项的最小距离),所以很快我就意识到我不能这么做,粗看了题解之后我才发现,做法其实应该是我一开始 pass 掉的 dp [ k ] [ i - 1 ] 表示在第 i 站设第 k 个补给站的最短路程,这样只要对于设置最后一个补给站的 dp 值加上剩下没有加的距离,就是最终结果。

    就这样,我基本理解了题目的做法,并且敲了一遍,然后就习惯性地 WA 了,昂,基本也属习惯,虽然我也一直在努力纠正,就是在很多我很习惯的模型上我一般不会敲错,但是这些新想的,专对题目的 dp 我却总是会出错,主要就是各种细节,特别是杭电对于各种细节坑非常扣。

    这题一点一点比对,才发现,坐标是有负数的,所以最好就是一开始把所有的坐标都弄成非负数,然后 dp 过程中也有各种小错误,一题大概当时做了一天吧,还是很心塞的。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #define min(a,b) a<b?a:b
     4 #define INF 0xFFFFFFF
     5 
     6 int a[205],dp[35][205],w[205][205];
     7 
     8 int main(){
     9     int n,m,c=0;
    10     while(scanf("%d%d",&n,&m)!=EOF&&n!=0||m!=0){
    11         int i,j,k,tmp,ans=INF;
    12         for(i=1;i<=n;i++){
    13             scanf("%d",&a[i]);
    14         }
    15         memset(w,0,sizeof(w));
    16         for(i=n;i>=1;i--){
    17             a[i]=a[i]-a[1]+1;
    18         }
    19         for(i=1;i<=n;i++){
    20             for(j=i;j<=n;j++){
    21                 tmp=0;
    22                 for(k=i;k<=j;k++){
    23                     
    24                     tmp+=min(a[k]-a[i],a[j]-a[k]);
    25                 }
    26                 w[i][j]=tmp;
    27             }
    28         }
    29 /*        
    30         printf("
    w:
    ");
    31         for(i=1;i<=n;i++){
    32             for(j=1;j<=n;j++){
    33                 printf("%3d",w[i][j]);
    34             }
    35             printf("
    ");
    36         }
    37         printf("
    ");
    38 */
    39     //    printf("min=%d
    ",min(a[3]-a[2],a[2]-a[1]));
    40 
    41         memset(dp,0,sizeof(dp));
    42         for(i=1;i<=n;i++){
    43             for(j=1;j<=i;j++){
    44                 dp[1][i]+=a[i]-a[j];
    45             }
    46         }
    47         for(j=2;j<=m;j++){
    48             for(i=j;i<=n;i++){
    49                 dp[j][i]=INF;
    50                 for(k=j-1;k<=i-1;k++){
    51                     dp[j][i]=min(dp[j][i],dp[j-1][k]+w[k][i]);
    52                 /*    
    53                     if(t==0){
    54                     printf("i=%d
    j=%d
    k=%d
    dp[j-1][k]=%d
    w(k,i)=%d
    ",i,j,k,dp[j-1][k],w[k][i]);
    55                     }
    56 */
    57                     
    58                 }
    59                 
    60             }
    61         }
    62 /*
    63         printf("
    ");
    64         for(j=1;j<=m;j++){
    65             for(i=1;i<=n;i++){
    66                 printf("%3d",dp[j][i]);
    67             }
    68             printf("
    ");
    69         }
    70         printf("
    ");
    71 */
    72         for(i=m;i<=n;i++){
    73             tmp=dp[m][i];
    74         //    printf("%d
    ",tmp);
    75             for(j=i+1;j<=n;j++){
    76                 tmp+=a[j]-a[i];
    77             }
    78             ans=min(ans,tmp);
    79         }
    80     //    printf("
    ");
    81         printf("Chain %d
    Total distance sum = %d
    
    ",++c,ans);
    82     }
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    javaScript中的onclick与jquery中的click区别
    javascript之parseInt的用法分析
    代码重构Refactor
    java-快捷生成Get/Set
    Java 调试和断点的介绍
    Java 运行报错:不支持发行版本 5
    实体类Json串转成DataTable
    sqlserver 如何瞬间执行上万条数据
    windows7远程连接服务器出现身份验证错误,又找不到加密Oracle修正
    MYSql 存储过程自定义跳出
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4322398.html
Copyright © 2011-2022 走看看