zoukankan      html  css  js  c++  java
  • luogu P1220 关路灯

    原题链接:https://www.luogu.org/problemnew/show/1220

    做过的唯一一道区间DP。

    首先说明题目中的贪心为什么是错的。由初中物理可知,消耗的电能是功率与时间的乘积,在此题中,所有没有被关掉的路灯每一秒都会耗电,不能单纯地用功率来考虑问题。

    发现贪心不成立,考虑区间DP,f[i][j][0/1]表示已经关闭了[i,j]的区间的路灯,当前在左/右侧。

    为了计算还没有关掉的路灯的耗能总和,使用前缀和。

    每次转移的时候,都有当前区间向左或是向右拓展的方案,而这期间消耗的能量就是区间之外所有路灯的功率之和与行走时间的乘积。

    #include<cstdio>
    void read(int &y)
    {
        y=0;char x=getchar();
        while(x<'0'||x>'9') x=getchar();
        while(x>='0'&&x<='9')
        {
            y=y*10+x-'0';
            x=getchar();
        }
    }
    int min(int x,int y)
    {
        if(x<y) return x;
        else return y;
    }
    int abs(int x)
    {
        if(x<=0) x*=-1;
        return x;
    }
    int n,c,x[55],w[55],f[55][55][2];
    int sum[55];
    int main()
    {
        read(n);read(c);
        for(int i=1;i<=n;i++)
        {
            read(x[i]);
            read(w[i]);
            sum[i]=sum[i-1]+w[i];
        }
        for(int i=1;i<=n;i++) f[i][i][0]=f[i][i][1]=sum[n]*abs(x[i]-x[c]);
        for(int l=2;l<=n;l++)
        {
            for(int i=1;i<=n-l+1;i++)
            {
                int j=i+l-1;
                f[i][j][0]=min(f[i+1][j][0]+(x[i+1]-x[i])*(sum[n]-sum[j]+sum[i]),f[i+1][j][1]+(x[j]-x[i])*(sum[n]-sum[j]+sum[i]));
                f[i][j][1]=min(f[i][j-1][1]+(x[j]-x[j-1])*(sum[n]-sum[j-1]+sum[i-1]),f[i][j-1][0]+(x[j]-x[i])*(sum[n]-sum[j-1]+sum[i-1]));
            }
        }
        printf("%d",min(f[1][n][0],f[1][n][1]));
        return 0;
    }
  • 相关阅读:
    LintCode Python 简单级题目 41.最大子数组
    helm深入学习
    kubernetes组件helm
    解压war包
    linux打开进程数测试
    docker使用centos7系统构建oraclejdk镜像
    docker使用centos7系统构建tomcat镜像
    docker使用alpine系统构建tomcat镜像
    docker制作共享jdk的tomcat镜像
    java cpu使用率高异常排查
  • 原文地址:https://www.cnblogs.com/zeroform/p/7802198.html
Copyright © 2011-2022 走看看