syhd142  
日历
<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
统计
  • 随笔 - 23
  • 文章 - 122
  • 评论 - 31
  • 引用 - 0

导航

常用链接

留言簿(2)

随笔档案(23)

文章分类(270)

文章档案(122)

我的豆瓣

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 
感觉又是一道经典的DP。
题意:给定v个村庄和p个邮局(v>=p),v个村庄在一条直线上,用一个整数值表示。求最佳的布置邮局方案使得每个村庄到最近的邮局距离之和最少。
思路:状态表示很容易想到,用opt[i][j]表示前i个邮局覆盖前j个村庄的最小距离之和。那么状态转移方程应该怎么表示呢?从当前状态opt[i][j]增加一个邮局,我们可以得到它到opt[i+1][j+k]的值(j+k<=v),即我们需要知道在任意两个村庄之间增加一个邮局的花费是多少,这样我们需要一个数组cost[i][j]保存在村庄i和j之间增加一个邮局所需要的花费,这部分需要预处理一下。这样我们就可以轻易地写出代码来了。
注意的地方:i>=j时显然opt[i][j]=0,因为邮局比村庄多。还有就是转移方程中的opt[i+1][j+k] = opt[i][j]+cost[j+1][j+k];注意cost中是从j+1到j+k的村庄中增加一个邮局的花费,因为第j个村庄的花费已经包含在opt[i][j]中了,开始这里写错了,答案一直不对。
#include <stdio.h>
#include 
<string.h>

#define N 305

int p[N], cost[N][N], opt[N][N];

inline 
int abs(int x)
{
    
return x > 0 ? x : -x;
}

int main()
{
    
int village, post;
    
while(~scanf("%d %d"&village, &post))
    {
        
if(post >= village)
        {
            puts(
"0");
            
continue;
        }
        memset(cost, 
0sizeof(cost));
        memset(opt, 
127sizeof(opt));
        
for(int i = 1; i <= village; i++)
            scanf(
"%d"&p[i]);
        
for(int i = 1; i <= village; i++)
            
for(int j = i + 1; j <= village; j++)
            {
                
int mid = (i + j) >> 1;
                
for(int k = i; k <= j; k++)
                    cost[i][j] 
+= abs(p[k] - p[mid]);
            }
        
for(int i = 1; i <= village; i++)
            opt[
1][i] = cost[1][i];
        
for(int i = 1; i < post; i++)
            
for(int j = i + 1; j <= village; j++)
            {
                
for(int k = 1; j + k <= village; k++)
                {
                    
if(opt[i][j] + cost[j + 1][j + k] < opt[i + 1][j + k])
                    {
                        opt[i 
+ 1][j + k] = opt[i][j] + cost[j + 1][j + k];
                    }
                }
            }
        printf(
"%d\n", opt[post][village]);
    }
    
return 0;
}
posted on 2010-06-08 18:04 Fucker 阅读(198) 评论(0)  编辑 收藏 引用 所属分类: ACM/ICPCDP

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


 
Copyright © Fucker Powered by: 博客园 模板提供:沪江博客