【刷题】【dp】关路灯
作者:互联网
为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电。
他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯。
现在已知老张走的速度为1m/s,每个路灯的位置(是一个整数,即距路线起点的距离,单位:m)、功率(W),老张关灯所用的时间很短而可以忽略不计。
请你为老张编一程序来安排关灯的顺序,使从老张开始关灯时刻算起所有灯消耗电最少(灯关掉后便不再消耗电了)。
看下面:
将点与点之间的互相影响,拆开成每个点对其他的影响,
从而使方程转移无后效性
f[i][j][0] = min ( f[i+1][j][0] + ( a[i+1] - a[i] ) * ( sum[i] + sum[n] - sum[j] ) , f[i+1][j][1] + ( a[j]-a[i] ) * ( sum[i]+sum[n]-sum[j]) );
f[i][j][1] = min ( f[i][j-1][0] + ( a[j] - a[i] ) * ( sum[i-1] + sum[n] - sum[j-1] ) , f[i][j-1][1] + ( a[j]-a[j-1] ) * ( sum[i-1] + sum[n] - sum[j-1] ) );
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; int n,st; const int N=53; struct node { int pos,p; bool operator < (const node & o) const { return pos<o.pos; } }d[N]; int f[N][N][2],sum[N]; int main() { scanf("%d%d",&n,&st); for(int i=1;i<=n;i++) scanf("%d%d",&d[i].pos ,&d[i].p ); for(int i=1;i<=n;i++) sum[i]=sum[i-1]+d[i].p ; memset(f,0x3f,sizeof(f)); f[st][st][0]=f[st][st][1]=0; for(int i=1;i<n;i++) for(int j=max(st-i,1),k=j+i;j<=st && k<=n;j++,k++) { f[j][k][0]=min(f[j+1][k][0]+(d[j+1].pos -d[j].pos )*(sum[n]-sum[k]+sum[j]), f[j+1][k][1]+(d[k].pos -d[j].pos )*(sum[n]-sum[k]+sum[j]) ); f[j][k][1]=min(f[j][k-1][1]+(d[k].pos -d[k-1].pos )*(sum[n]-sum[k-1]+sum[j-1]), f[j][k-1][0]+(d[k].pos -d[j].pos )*(sum[n]-sum[k-1]+sum[j-1]) ); } printf("%d\n",min(f[1][n][0],f[1][n][1])); return 0; }
标签:路灯,老张,const,sum,关灯,include,dp,刷题 来源: https://www.cnblogs.com/xwww666666/p/11716055.html