hdu1227 Fast Food

这个题目如果直接暴力枚举的话,复杂度是n*C(n,k),最坏情况约10^37。

考察下面这种情况:

(n=5,k=3,粗体及加下划线的节点为depot所在地)

    ③    ⑤

  ②      ⑤

对于④及以后的节点,在④被选中后,距离它们最短的depot一定不会在④之前(因为距离一定比④远)。

也就是说④及之后节点的最优情况与④之前的节点无关,图示两种情况对于④及以后节点是等价的。

状态基本上就出来了。

我从中提取出的状态是[s][num],表示在s号节点被选定后,节点s……n之间还剩num个位置要选时的最优值。

预处理出disSum[N][N]数组,表示在节点i和节点j被选定后(j>i),i……j之间的节点的取值(跟着i还是j)之和。

那么,

  dp[s][num]=min( dp[i][num-1] + disSum[s][i] )    i=s+1……n-num+1

复杂度是O(n*n*k)

/*

  设计状态的时候,如果[s][num]表示的是节点s……n还剩num个位置要选时的最优值,并不要求节点s已被选定的话,这个dp就不成立了。

     [3][1]的最优方案是:③    ⑤

     [2][2]的最优方案是(可以构造这样的例子):  ③    ⑤, ③节点距离②节点更近,此时[3][1]的最优值也就改变了,不满足无后效性。

*/

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N = 205,K = 35,INF = 0x7fffffff;
 6 
 7 int dp[N][K],n,m;
 8 int dis[N],disSum[N][N];
 9 
10 int solve(int s,int num)
11 {
12     if( dp[s][num]!=-1 )    return dp[s][num];
13     int ret=INF;
14     if( !num )
15     {
16         ret=0;
17         for(int i=s+1;i<=n;i++)
18             ret+=dis[i]-dis[s];
19         return ret;
20     }
21     for(int i=s+1;i<=n-num+1;i++)
22         ret=min(ret,disSum[s][i]+solve(i,num-1));
23     return dp[s][num]=ret;
24 }
25 
26 int main()
27 {
28     int t=0;
29     while( scanf("%d%d",&n,&m),n||m )
30     {
31         memset(dp,-1,sizeof(dp));
32         dis[0]=0;
33         for(int i=1;i<=n;i++)
34             scanf("%d",&dis[i]);
35         for(int i=1;i<n;i++)
36             for(int j=i+1;j<=n;j++)
37             {
38                 int sum=0;
39                 for(int k=i;k<=j;k++)
40                     sum+=min(dis[k]-dis[i],dis[j]-dis[k]);
41                 disSum[i][j]=sum;
42             }
43         int ans=INF;
44         for(int i=1;i<=n-m+1;i++)
45         {
46             int sum=0;
47             for(int j=1;j<=i;j++)   sum+=dis[i]-dis[j];
48             ans=min(ans,sum+solve(i,m-1));
49         }
50         printf("Chain %d\n",++t);
51         printf("Total distance sum = %d\n\n",ans);
52     }
53     return 0;
54 }
55 /*
56     这个稍有些难想,对无后效性再有了理解。
57 */

 

posted @ 2013-02-02 21:29  kiwi_bird  阅读(275)  评论(0编辑  收藏  举报