• 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;
    }
  • 相关阅读:
    Java HashMap 和 ConcurrentHashMap
    递归算法应用
    二叉树基础知识
    自动删除qq空间说说
    移动APP测试的22条军规--笔记
    SQL Server数据库状态监控
    SqlSugar-事务操作
    详解第一范式、第二范式、第三范式、BCNF范式
    SQL 日期
    2019年世界各国gdp排名对比
  • 原文地址:https://www.cnblogs.com/zeroform/p/7802198.html
Copyright © 2020-2023  润新知