码迷,mamicode.com
首页 > 其他好文 > 详细

hdu1227 dp

时间:2015-03-08 22:53:50      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

题意:在一条路上有 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("\nw:\n");
31         for(i=1;i<=n;i++){
32             for(j=1;j<=n;j++){
33                 printf("%3d",w[i][j]);
34             }
35             printf("\n");
36         }
37         printf("\n");
38 */
39     //    printf("min=%d\n",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\nj=%d\nk=%d\ndp[j-1][k]=%d\nw(k,i)=%d\n",i,j,k,dp[j-1][k],w[k][i]);
55                     }
56 */
57                     
58                 }
59                 
60             }
61         }
62 /*
63         printf("\n");
64         for(j=1;j<=m;j++){
65             for(i=1;i<=n;i++){
66                 printf("%3d",dp[j][i]);
67             }
68             printf("\n");
69         }
70         printf("\n");
71 */
72         for(i=m;i<=n;i++){
73             tmp=dp[m][i];
74         //    printf("%d\n",tmp);
75             for(j=i+1;j<=n;j++){
76                 tmp+=a[j]-a[i];
77             }
78             ans=min(ans,tmp);
79         }
80     //    printf("\n");
81         printf("Chain %d\nTotal distance sum = %d\n\n",++c,ans);
82     }
83     return 0;
84 }
View Code

 

hdu1227 dp

标签:

原文地址:http://www.cnblogs.com/cenariusxz/p/4322398.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!