• POJ1821 Fence(单调队列)


    /*
        设计状态f[i][j]表示前i人涂前j个,然后进行转移
        发现其中一部分可以通过单调队列维护降低复杂度
    */
    #include<iostream>
    #include<queue>
    #include<map>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=1e5+7;
    const int inf=0x3f3f3f3f;
    int n,k;
    struct node{
        int l,p,s;
    }s[N];
    int q[N];
    int f[110][16100];
    bool cmp(node a,node b){
        return a.s<b.s;
    }
    int main(){
        cin>>n>>k;
        int i;
        for(i=1;i<=k;i++){
          cin>>s[i].l>>s[i].p>>s[i].s;
        }
        sort(s+1,s+1+k,cmp);
        int j;
        memset(f,0,sizeof f);
        int hh=0;
        int tt=-1;
        for(i=1;i<=k;i++){
            hh=0;
            tt=0;
            q[0]=0;//队首0,当前唯一合法状态
            for(j=1;j<=n;j++){
                f[i][j]=max(f[i-1][j],f[i][j-1]);//该木匠不刷的情况
                if(j>=s[i].s+s[i].l)//涂不到但不能break,因为可能前面的工人也能涂到后面的板子
                    continue;
                while(hh<=tt&&q[hh]+s[i].l<j)//当超过涂的范围就要除去
                    hh++;
                if(j<s[i].s){//将可能的情况放入队列中
                    int tmp=f[i-1][j]-s[i].p*j;
                    while(hh<=tt&&f[i-1][q[tt]]-s[i].p*q[tt]<tmp)
                        tt--;
                    q[++tt]=j;
                    continue;
                }
                f[i][j]=max(f[i][j],f[i-1][q[hh]]+s[i].p*(j-q[hh]));
            }
        }
        cout<<f[k][n]<<endl;
    }
    View Code

    解释看代码

  • 相关阅读:
    caffe学习
    阅读文献的三大问题:坐不住,记不住,想不开
    第五章 MySQL函数
    第四章 MySQL数据类型和运算符
    第三章 数据表的基本操作
    第二章 数据库的基本操作
    EXCEL的导入导出
    JAVA 通过位运算进行简单的加密
    JAVA 从控制台接收输入的字符
    JAVA Web JS
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12454694.html
Copyright © 2020-2023  润新知