洛谷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;//拜拜程序~ }

转载于:https://www.cnblogs.com/SHADOWICENCXIX/p/7672720.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值