【刷题】【dp】关路灯 && 边奔跑边吃草

【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\n",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\n",min(f[1][n][0],f[1][n][1]));
    return 0;
}

 

posted @ 2019-10-21 20:53  心若笺诗  阅读(187)  评论(0编辑  收藏  举报