ACM PKU 1160 Post Office 经典动态规划

ACM PKU 1160 Post Office 经典动态规划

http://acm.pku.edu.cn/JudgeOnline/problem?id=1160
用opt[i][j]记录把前i个邮局建到前j个村庄中的最优解
用cost[i][j]记录所有在i到j村庄中,建1个邮局的最小代价。显然邮局应该设到中点。

让前i个邮局覆盖前j个村庄,第i+1个邮局覆盖第j+1至j+k个村庄(j+k<=n),则状态转移方程为
 opt[i+1][j+k]=min{opt[i][j]+cost[j+1][j+k];}  (k+j<=n)


#include " stdio.h "
long  cost[ 301 ][ 301 ];
long  opt[ 301 ][ 301 ];         // 把前i个邮局建到前j个村庄中的最优解
int  v[ 301 ];


void  pre( int  m, int  n)
{
    
int i,j,mid,k;              //记录所有在i到j村庄中,建一个邮局的最小代价。显然邮局应该设到中点。
    for (i=1;i<=m;i++)
        
for(j=i;j<=m;j++)         //j>=i
        {
            cost[i][j]
=0;
            mid
=(i+j)/2;
            
for(k=i;k<=mid;k++)
                cost[i][j]
+=v[mid]-v[k];
            
for(k=mid+1;k<=j;k++)
                cost[i][j]
+=v[k]-v[mid];
        }


}

void  main()
{
    
    
int i,j,k;
    
int m,n;
    
    scanf(
"%d%d",&m,&n);
    
for(i=1;i<=m;i++)
        scanf(
"%d",&v[i]);
    pre(m,n);


    
for(i=0;i<=n;i++)
        
for(j=0;j<=m;j++)
            opt[i][j]
=3000000;
    opt[
0][0]=0;
     
for(i=0;i<=n;i++)
       
for(j=0;j<=m;j++)
           
if(opt[i][j]<3000000)
        
{
            
for(k=1;j+k<=m;k++)
                
if(opt[i+1][j+k]>opt[i][j]+cost[j+1][j+k])       //状态转移.   让前i个邮局覆盖前j个村庄,第i+1个邮局覆盖第j+1到第j+k个村庄。
                   opt[i+1][j+k]=opt[i][j]+cost[j+1][j+k];
        }

       printf(
"%d\n", opt[n][m]);
       

}

你可能感兴趣的:(ACM PKU 1160 Post Office 经典动态规划)