• 洛谷P1220 关路灯题解


    这道题是一道区间dp的题目

    我们如何看出他是区间dp?

    因为他是在一条线上从小区间不断向大区间扩散,长度不断增加,所以大区间的答案一定是从小区间的答案更新而来

    题目已知的信息有区间位置,和功率和米数,所以我们要从这些信息入手。

    如何设计dp状态?

    我们观察到我们需要保存小区间的答案,所以我们前两维可以定位i-j区间都被关闭的最小功率,但是这样显然还是不够的,我们还要一种状态叫做向左向右。

    所以我们可以设计第三维为在左端点和右端点,根据他来更新之后向左和向右的答案。

    消耗可以用作功率*米数,我们还需要保存sum数组,用来保存任意区间内在1s内消耗的功率,这样就能更新所有状态

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=110;
    struct node{
        int p;
        int x;
    }s[N];
    int f[N][N][2];
    int sum[N][N];
    int main(){
        int n;
        int c;
        cin>>n>>c;
        int i;
        for(i=1;i<=n;i++){
            cin>>s[i].x>>s[i].p;
        }
        int j;
        for(i=1;i<=n;i++){
            sum[i][i]=s[i].p;
            for(j=i+1;j<=n;j++){
                sum[i][j]=sum[i][j-1]+s[j].p;
            }
        }
        memset(f,0x3f,sizeof f);
        f[c][c][0]=f[c][c][1]=0;
        int len;
        int l,r;
        for(len=2;len<=n;len++){
            for(l=1;l+len-1<=n;l++){
                r=l+len-1;
                f[l][r][0]=min(f[l+1][r][0]+(s[l+1].x-s[l].x)*(sum[1][l]+sum[r+1][n]),f[l+1][r][1]+(s[r].x-s[l].x)*(sum[1][l]+sum[r+1][n]));
                f[l][r][1]=min(f[l][r-1][1]+(s[r].x-s[r-1].x)*(sum[1][l-1]+sum[r][n]),f[l][r-1][0]+(s[r].x-s[l].x)*(sum[1][l-1]+sum[r][n]));
            }
        }
         cout<<min(f[1][n][0],f[1][n][1])<<endl;    
    }
    View Code
  • 相关阅读:
    ubuntu 访问 共享 windows文件夹
    ubuntu下android环境的搭建
    smb使用 ------转载自http://blog.csdn.net/tlaff/article/details/5463068
    oracle jar
    悬浮按钮
    移动开发赚钱
    截取scrollview的滑动事件,传递给子控件
    put ListView in a ScrollView(bug fixed)
    35岁前务必成功的12级跳
    mysql分页原理和高效率的mysql分页查询语句
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12242235.html
Copyright © 2020-2023  润新知