zoukankan      html  css  js  c++  java
  • POJ 1821 Fence(单调队列优化DP)

    题解

    以前做过很多单调队列优化DP的题。

    这个题有一点不同是对于有的状态可以转移,有的状态不能转移。

    然后一堆边界和注意点。导致写起来就很难受。

    然后状态也比较难定义。

    dp[i][j]代表前i个人涂完前j个位置的最大收益。

    然后转移考虑

    第i个人可以不刷。dp[i][j]=dp[i-1][j];

    第j个木板可以不刷dp[i][j]=dp[i][j-1];

    然后当c[i].s<=j<=s[i]+l[i]-1时

    dp[i][j]=p[i]*j+max(dp[i-1][k]-p[i]*k)其中j-l[i]<=k<=s[i]-1;

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=20000;
     8 const int M=210;
     9 int dp[M][N],n,m,q[N],head,tail,ans;
    10 struct people{
    11     int l,p,s;
    12 }c[M];
    13 bool cmp(people a,people b){
    14     return a.s<b.s;
    15 }
    16 int read(){
    17     int sum=0,f=1;char ch=getchar();
    18     while(ch<'0'||ch>'9'){
    19         if(ch=='-')f=-1;
    20         ch=getchar();
    21     }
    22     while(ch>='0'&&ch<='9'){
    23         sum=sum*10+ch-'0';
    24         ch=getchar();
    25     }
    26     return sum;
    27 }
    28 int main(){
    29     while(scanf("%d%d",&n,&m)!=EOF){
    30         memset(dp,0,sizeof(dp));
    31         for(int i=1;i<=m;i++){
    32             c[i].l=read();c[i].p=read();c[i].s=read();
    33         }
    34         sort(c+1,c+1+m,cmp);
    35         for(int i=1;i<=m;i++){
    36             memset(q,0,sizeof(q));
    37             head=1;tail=1;
    38             for(int j=1;j<=n;j++){
    39                 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
    40                 if(j>=c[i].s&&j<=c[i].s+c[i].l-1){
    41                     while(head<=tail&&q[head]<j-c[i].l)head++;
    42                     if(head>tail)continue;
    43                     dp[i][j]=max(c[i].p*j+dp[i-1][q[head]]-c[i].p*q[head],dp[i][j]);
    44                 }
    45                 if(j<c[i].s){
    46                     while(head<=tail&&dp[i-1][j]-c[i].p*j>=dp[i-1][q[tail]]-c[i].p*q[tail])tail--;
    47                     q[++tail]=j;
    48                 }
    49             }
    50         }
    51         printf("%d
    ",dp[m][n]);
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    如何解决UITextField挡住键盘的问题
    设置UITextField中能输入的最大的字数
    如何判断IOS的设备版本型号
    IOS中如何实现对话聊天
    精美的iOS图片欣赏
    关于IOS 应用图标的设置
    ios7中添加多个按钮
    elementary0.4:快速配置工具
    elementary:网易云音乐白条解决
    deepin下eclipse快捷方式
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9757131.html
Copyright © 2011-2022 走看看