zoukankan      html  css  js  c++  java
  • 【刷题】【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
    ",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;
    }
  • 相关阅读:
    nodejs-supervisor
    javascript数组操作(创建、元素删除、数组的拷贝)
    mysql索引优化-order/group
    php-kafka
    大流量高并发解决方案
    MySQL数据类型和常用字段属性总结
    php一致性hash算法
    面试中的排序算法总结
    PHP的运行机制与原理(底层)
    Mysql中的锁机制
  • 原文地址:https://www.cnblogs.com/xwww666666/p/11716055.html
Copyright © 2011-2022 走看看