• 题解 P1220 【关路灯】


    题目链接:Link

    Problem

    Solution

    考虑到如果经过一个路灯,显然可以直接随手把它关掉,毕竟关灯不耗时,因此,必定有一种最优解满足:任何时候已关的灯都是一个连续的序列。
    则确定一个状态需要3个变量:左端点,右端点,关完后的位置。
    尝试写出转移方程,发现无误,即得解。

    Code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int maxn=55;
    int n,c,p[maxn],w[maxn];
    LL s[maxn],f[maxn][maxn][2];
    int main()
    {
    	#ifdef local
    	freopen("pro.in","r",stdin);
    	#endif
    	scanf("%d%d",&n,&c);
    	for(int i=1;i<=n;i++) scanf("%d%d",&p[i],&w[i]);
    	for(int i=1;i<=n;i++) s[i]=s[i-1]+w[i];
    	memset(f,0x3f,sizeof(f));
    	f[c][c][0]=f[c][c][1]=0;
    	for(int len=1;len<n;len++)
    		for(int i=1;i+len-1<=n;i++)
    		{
    			int j=i+len-1;
    			LL W=s[i-1]+s[n]-s[j];
    			if(i>1) f[i-1][j][0]=min(f[i-1][j][0],min(f[i][j][0]+(p[i]-p[i-1])*W,f[i][j][1]+(p[j]-p[i-1])*W));
    			if(j<n) f[i][j+1][1]=min(f[i][j+1][1],min(f[i][j][0]+(p[j+1]-p[i])*W,f[i][j][1]+(p[j+1]-p[j])*W));
    		}
    	printf("%lld
    ",min(f[1][n][0],f[1][n][1]));
    	return 0;
    }
    
  • 相关阅读:
    洛谷 P1628 合并序列
    洛谷 P3378 【模板】堆
    浅谈可删除堆
    浅谈数据结构—分块
    浅谈对顶堆
    JDOJ 1929: 求最长不下降序列长度
    JDOJ 1928: 排队买票
    Leetcode(53)-最大子序和
    Leetcode(38)-报数
    Leetcode(35)-搜索插入位置
  • 原文地址:https://www.cnblogs.com/happyZYM/p/11728458.html
Copyright © 2020-2023  润新知