心如止水
Je n'ai pas le temps
posts - 400,comments - 130,trackbacks - 0
假设此时已经安慰好了第i个MM和第j个MM及其之间的所有MM。如果此时站在第i个MM所在的位置,用d[i,j,0]表示之后需要消耗的最小RP;如果此时站在第j个MM所在的位置,用d[i,j,1]表示在此之后需要消耗的最小RP。
那么就有:
d[i,j,0]=min{ d[i-1,j,0]+abs(r[i]-r[i-1])*(s[n]-s[j]+s[i-1]),
                     d[i,j+1,1]+abs(r[i]-r[j+1])*(s[n]-s[j]+s[i-1]) };
d[i,j,1]时的情况可以类似写出。
其中r[i]表示第i个MM所在的位置,s[i]表示前i个MM的w[i]的和。
以下是我的代码:
#include<iostream>
#include
<string.h>
#include
<stdlib.h>
#define maxn 1007
#define inf 2000000000
using namespace std;
long min(long a,long b){return (a<b?a:b);}

long n,v,r[maxn],w[maxn],s[maxn];
long d[maxn][maxn][2];

long dp(long i,long j,long k)
{
    
if(d[i][j][k]!=-1return d[i][j][k];
    d[i][j][k]
=inf;
    
if(k==0)
    {
       
if(i-1>=0)
         d[i][j][k]
=min(d[i][j][k],dp(i-1,j,0)+abs(r[i]-r[i-1])*(s[n]-s[j]+s[i-1]));
       
if(j+1<=n+1)
         d[i][j][k]
=min(d[i][j][k],dp(i,j+1,1)+abs(r[i]-r[j+1])*(s[n]-s[j]+s[i-1]));
    }
    
else if(k==1)
    {
       
if(i-1>=0)
         d[i][j][k]
=min(d[i][j][k],dp(i-1,j,0)+abs(r[j]-r[i-1])*(s[n]-s[j]+s[i-1]));
       
if(j+1<=n+1)
         d[i][j][k]
=min(d[i][j][k],dp(i,j+1,1)+abs(r[j]-r[j+1])*(s[n]-s[j]+s[i-1]));
    }
    
return d[i][j][k];
}

int main()
{
    cin
>>n>>v;
    s[
0]=0;
    
for(long i=1;i<=n;i++)
    {
       cin
>>r[i]>>w[i];
       s[i]
=s[i-1]+w[i];
    }
    
//  Input
    
    memset(d,
-1,sizeof(d));
    d[
0][n+1][0]=d[0][n+1][1]=0;
    
//  Init
    
    cout
<<dp(v,v,0)<<endl;
    
//  Output
return 0;
}
posted on 2010-10-30 20:15 lee1r 阅读(523) 评论(0)  编辑 收藏 引用 所属分类: 题目分类:动态规划

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