洛谷1220
dp三要素,状态定义,转移方程,边界条件!边界条件!边界条件!
不要以为方程出来了就万事大吉,还有边界条件!!!!!!
方程和楼下用的一样
dp[i][j][0]=min(dp[i+1][j][1]+sum(i+1,j)*(t[j]-t[i]),dp[i+1][j][0]+sum(i+1,j)*(t[i+1]-t[i]));
dp[i][j][1]=min(dp[i][j-1][1]+sum(i,j-1)*(t[j]-t[j-1]),dp[i][j-1][0]+sum(i,j-1)*(t[j]-t[i]));
其中dp[i][j][k]表示i到j区间的灯已灭,k=0老王在左端点,k=1老王在右端点。
sum(i,j)计算i到j的灯灭了以后剩余灯的功耗,t[i]是点i的距离。
然而我们发现,仅仅是dp[st][st][0]=0;dp[st][st][1]=0;
是不够的,这样在计算以st为起点和终点时,会有出发电灯亮着的鬼畜情况。。。
(因为方程鲁棒的把i+1,把j-1)
所以我们还需要专门针对i=st,j=st的转移方程!
dp[st-1][j][1]=dp[st-1][j-1][1]+sum(st-1,j-1)*(t[j]-t[j-1]);
dp[st-1][j][0]=dp[st-1][j][1]+sum(st-1,j)*(t[j]-t[st-1]);
dp[i][st-1][0]=dp[i+1][st-1][0]+sum(i+1,st-1)*(t[i+1]-t[i]);
dp[i][st-1][1]=dp[i][st-1][0]+sum(i,st-1)*(t[st-1]-t[i]);
上代码~
#include<stdio.h>
#include<algorithm>
using namespace std;
int n;int st;
int t[50];int w[50];
int dp[50][50][2];
int sum(int a,int b)
{
int res=0;
if(a>st-1)a=st-1;//粗暴的处理边界转移方程的非法情况,但无法处理普通转移的非法情况
if(b<st-1)b=st-1;
for(int i=0;i<n;i++)
{
if(i>=a&&i<=b)continue;
res+=w[i];
}
//printf("sum(%d,%d)is%d\n",a,b,res);
return res;
}
int main()
{
scanf("%d%d",&n,&st);
for(int i=0;i<n;i++)
{
scanf("%d%d",&t[i],&w[i]);
}
if(n==1)
{
printf("0");return 0;
}
dp[st-1][st-1][0]=0;dp[st-1][st-1][1]=0;//定义原点
for(int j=st;j<n;j++)//从零开始的数组
{
dp[st-1][j][1]=dp[st-1][j-1][1]+sum(st-1,j-1)*(t[j]-t[j-1]);//递推以出发点为起点情况
dp[st-1][j][0]=dp[st-1][j][1]+sum(st-1,j)*(t[j]-t[st-1]);
}
for(int i=st-2;i>=0;i--)
{
dp[i][st-1][0]=dp[i+1][st-1][0]+sum(i+1,st-1)*(t[i+1]-t[i]);//递推以出发点为终点情况
dp[i][st-1][1]=dp[i][st-1][0]+sum(i,st-1)*(t[st-1]-t[i]);
}
for(int i=st-2;i>=0;i--)//没啥好说的dp,楼下讲的很详细
{
for(int j=st;j<n;j++)
{
dp[i][j][0]=
min(dp[i+1][j][1]+sum(i+1,j)*(t[j]-t[i]),
dp[i+1][j][0]+sum(i+1,j)*(t[i+1]-t[i]));
dp[i][j][1]=
min(dp[i][j-1][1]+sum(i,j-1)*(t[j]-t[j-1]),
dp[i][j-1][0]+sum(i,j-1)*(t[j]-t[i]));
}
}
/*for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
printf("%-4d",dp[i][j][0]);
}
printf("\n");
}
printf("\n");
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
printf("%-4d",dp[i][j][1]);
}
printf("\n");
}*/
int res=min(dp[0][n-1][0],dp[0][n-1][1]);//不知道最后老王在路左还是路右,二者取其min
printf("%d",res);
return 0;//拜拜程序~
}
posted on 2017-10-15 17:04 SHADOWICENCXIX 阅读(108) 评论(0) 编辑 收藏 举报