【1】关路灯
为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电。
他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯。
现在已知老张走的速度为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 ",min(f[1][n][0],f[1][n][1])); return 0; }
【2】边奔跑边吃草
John养了一只叫Joseph的奶牛。一次她去放牛,来到一个非常长的一片地,上面有N块地方长了茂盛的草。我们可
以认为草地是一个数轴上的一些点。Joseph看到这些草非常兴奋,它想把它们全部吃光。于是它开始左右行走,吃
草。John和Joseph开始的时候站在p位置。Joseph的移动速度是一个单位时间一个单位距离。不幸的是,草如果长
时间不吃,就会腐败。我们定义一堆草的腐败值是从Joseph开始吃草到吃到这堆草的总时间。Joseph可不想吃太腐
败的草,它请John帮它安排一个路线,使得它吃完所有的草后,总腐败值最小。John的数学很烂,她不知道该怎样
做,你能帮她么?
与上题类似,但是有个wa点,
以后计算一下范围,有加法的还是0x3f靠谱
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; int n,st; const int N=1003; int p[N],f[N][N][2]; int main() { scanf("%d%d",&n,&st); for(int i=1;i<=n;i++) scanf("%d",&p[i]); sort(p+1,p+n+1); memset(f,0x3f,sizeof(f));//0x7f他爆了......直接wa 4个点 int pos=lower_bound(p+1,p+n+1,st)-p; if(p[pos]==st) f[pos][pos][0]=f[pos][pos][1]=0; else { if(pos>1) f[pos-1][pos-1][0]=f[pos-1][pos-1][1]=n*(st-p[pos-1]);//打标点的时候还是注意下,',' 和 ';' ,特别是放在末尾的时候 f[pos][pos][0]=f[pos][pos][1]=n*(p[pos]-st); } for(int len=1,res=n-1 ; res>0 ; len++,res-- ) for(int i=1,j=i+len;j<=n;i++,j++) { f[i][j][0]=min( f[i+1][j][0]+(p[i+1]-p[i])*res , f[i+1][j][1]+(p[j]-p[i])*res ); f[i][j][1]=min( f[i][j-1][1]+(p[j]-p[j-1])*res , f[i][j-1][0]+(p[j]-p[i])*res ); } printf("%d ",min(f[1][n][0],f[1][n][1])); return 0; }