• 线性DP


    LCIS

    单调优化思想

     1     a[0]=b[0]=-9999;
     2     FOR(i,1,n)
     3     {
     4         int val=0;
     5         if(b[0]<a[i]) val=f[i-1][0];
     6         FOR(j,1,n) 
     7         {
     8             if(a[i]==b[j]) f[i][j]=val+1;
     9             else f[i][j]=f[i-1][j];
    10             if(b[j]<a[i]) val=max(val,f[i-1][j]);
    11         }
    12     }
    13     FOR(i,1,n) ans=max(f[n][i],ans);
    14     printf("%d",ans);

    CH5102 Mobile Service http://contest-hunter.org:83/contest/0x50%E3%80%8C%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E3%80%8D%E4%BE%8B%E9%A2%98/5102%20Mobile%20Service

    三人的相对顺序不重要,考虑只记录两个不确定的位置

     1 inline int rd()
     2 {
     3     rg int x(0),w(1);
     4     rg char c(gc);
     5     while(c<'0'||c>'9') {if(c=='-')w=-1;c=gc;}
     6     while(c>='0'&&c<='9') x=x*10+c-48,c=gc;
     7     return x*w;
     8 }
     9 
    10 
    11 void scan()
    12 {
    13     l=rd();n=rd();
    14     FOR(i,1,l) FOR(j,1,l) c[i][j]=rd();
    15     FOR(i,1,n) q[i]=rd();
    16     memset(f,8,sizeof(f));
    17 }
    18 
    19 
    20 void dp()
    21 {
    22     q[0]=3;f[0][1][2]=0;
    23     FOR(i,0,n-1) FOR(j,1,l) FOR(k,1,l) if(j!=k&&f[i][j][k]<=100000000)
    24     {
    25         if(j!=k   &&q[i+1]!=j   &&q[i+1]!=k) gmin(f[i+1][j][k],f[i][j][k]+c[q[i]][q[i+1]]);
    26         if(q[i]!=k&&q[i+1]!=q[i]&&q[i+1]!=k) gmin(f[i+1][q[i]][k],f[i][j][k]+c[j][q[i+1]]);
    27         if(q[i]!=j&&q[i+1]!=q[i]&&q[i+1]!=j)gmin(f[i+1][j][q[i]],f[i][j][k]+c[k][q[i+1]]);
    28     }
    29 }
    30 
    31 void print()
    32 {
    33     FOR(i,1,l) FOR(j,1,l) ans=min(ans,f[n][i][j]);
    34     printf("%d",ans);
    35 }
    View Code

    P1006 传纸条https://www.luogu.org/problemnew/show/P1006

    两条路同时走,将能用1、2、3维确定的第4维压掉

    FOR(i,1,m) FOR(j,1,n) FOR(k,max(i+j-n,1),min(i+j-1,m))
        {
            if(i==1&&j==1) f[i][j][k]=0;
            else if(i==k  && !(i==m&&j==n)) f[i][j][k]=-9999999;
            else f[i][j][k]=a[i][j]+a[k][i+j-k]+
            max(f[i-1][j][k-1],max(f[i][j-1][k-1],max(f[i-1][j][k],f[i][j-1][k])));
        }
        cout<<f[m][n][m];

    CH5104 I-country http://contest-hunter.org:83/contest/0x50%E3%80%8C%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E3%80%8D%E4%BE%8B%E9%A2%98/5104%20I-country

    凸连痛快问题,利用两个维度分别记录左右边界的单调性

     1 const int N=16,K=230;
     2 struct hhh{int ii,jj,ll,rr,xx,yy;}pre[N][K][N][N][2][2];
     3 int f[N][K][N][N][2][2],a[N][N];
     4 int n,m,k;
     5 
     6 void scan()
     7 {
     8     n=rd();m=rd();k=rd(); 
     9     FOR(i,1,n) FOR(j,1,m) a[i][j]=rd(); 
    10     //memset(f,-8,sizeof(f));
    11     //FOR(i,1,n) f[i][0][0][0][1][0];
    12     //FOR(i,1,n){FOR(j,1,m)printf("%d",a[i][j]);printf("
    ");}
    13 }
    14 
    15 void work()
    16 {
    17     FOR(i,1,n) FOR(j,1,k) FOR(l,1,m) for(rg int r=l;r<=m&&r-l<j;++r)
    18     {
    19         int t=0;FOR(ii,l,r) t+=a[i][ii];
    20         int cz=r-l+1;
    21         //only widen 
    22         if(j==cz) 
    23             f[i][j][l][r][1][0]=t+f[i-1][0][0][0][1][0];
    24         else 
    25         {
    26             //only widen
    27             FOR(p,l,r) FOR(q,p,r)
    28                 if(f[i][j][l][r][1][0]<f[i-1][j-cz][p][q][1][0])
    29                     f[i][j][l][r][1][0]=f[i-1][j-cz][p][q][1][0],
    30                     pre[i][j][l][r][1][0]={i-1,j-cz,p,q,1,0};
    31             //both right
    32             FOR(p,1,l) FOR(q,l,r) FOR(x,0,1)
    33                 if(f[i][j][l][r][0][0]<f[i-1][j-cz][p][q][x][0])
    34                     f[i][j][l][r][0][0]=f[i-1][j-cz][p][q][x][0],
    35                     pre[i][j][l][r][0][0]={i-1,j-cz,p,q,x,0};
    36             //both left
    37             FOR(p,l,r) FOR(q,r,m) FOR(x,0,1)
    38                 if(f[i][j][l][r][1][1]<f[i-1][j-cz][p][q][1][x])
    39                     f[i][j][l][r][1][1]=f[i-1][j-cz][p][q][1][x],
    40                     pre[i][j][l][r][1][1]={i-1,j-cz,p,q,1,x};
    41             //both unwiden
    42             FOR(p,1,l) FOR(q,r,m) FOR(x,0,1) FOR(y,0,1)
    43                 if(f[i][j][l][r][0][1]<f[i-1][j-cz][p][q][x][y])
    44                     f[i][j][l][r][0][1]=f[i-1][j-cz][p][q][x][y],
    45                     pre[i][j][l][r][0][1]={i-1,j-cz,p,q,x,y};
    46             FOR(x,0,1) FOR(y,0,1) f[i][j][l][r][x][y]+=t;
    47         }
    48         //printf("%d %d %d %d %d %d %d %d %d
    ",i,j,l,r,t,
    49         //f[i][j][l][r][1][0],f[i][j][l][r][0][0],f[i][j][l][r][1][1],f[i][j][l][r][0][1]);
    50     }
    51 }
    52 
    53 void dg(hhh ans)
    54 {
    55     if(!ans.jj) return;
    56     dg(pre[ans.ii][ans.jj][ans.ll][ans.rr][ans.xx][ans.yy]);
    57     FOR(i,ans.ll,ans.rr) printf("%d %d
    ",ans.ii,i);
    58 }
    59 
    60 void print()
    61 {
    62     int ans=-99999999;hhh as;
    63     FOR(i,1,n) FOR(l,1,m) FOR(r,l,m) FOR(x,0,1) FOR(y,0,1) 
    64         if(ans<f[i][k][l][r][x][y])
    65             ans=f[i][k][l][r][x][y],
    66             as={i,k,l,r,x,y};
    67     printf("Oil : %d
    ",ans);
    68     dg(as);
    69 }

    CH5105 Cookies http://contest-hunter.org:83/contest/0x50%E3%80%8C%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E3%80%8D%E4%BE%8B%E9%A2%98/5105%20Cookies

    代价倒序排序,由于最后每人饼干数单调递减,每次转移

    a.给每人发一个

    b.给i前面的k个人分别发一个

    const int N=32,M=5002;
    int g[N],f[N][M],a[N][M],b[N][M],c[N],ans[N],ran[N];
    int n,m;
    
    bool cmp(int x,int y){return g[x]>g[y];}
    
    void scan()
    {
        n=rd();m=rd();
        FOR(i,1,n) g[i]=rd(),ran[i]=i;
        sort(ran+1,ran+n+1,cmp);
        //FOR(i,1,n)printf("%d ",g[i]);
        FOR(i,1,n) c[i]=c[i-1]+g[ran[i]];
        memset(f,8,sizeof(f));
        f[0][0]=0;
    }
    
    void work()
    {
        FOR(i,1,n) FOR(j,i,m)
        {
            f[i][j]=f[i][j-i];
            a[i][j]=i,b[i][j]=j-i;
            FOR(k,0,i-1) 
                if(f[i][j]>f[k][j-(i-k)]+k*(c[i]-c[k]))
                    f[i][j]=f[k][j-(i-k)]+k*(c[i]-c[k]),
                    a[i][j]=k,b[i][j]=j-(i-k);
        }
    }
    
    void dg(int n,int m)
    {
        if(n==0) return;
        dg(a[n][m],b[n][m]);
        if(a[n][m]==n)
            FOR(i,1,n) ans[ran[i]]++;
        else
            FOR(i,a[n][m]+1,n) ans[ran[i]]=1;
    }
    
    void print()
    {
        printf("%d
    ",f[n][m]);
        dg(n,m);
        FOR(i,1,n) printf("%d ",ans[i]);
    }

    P1541 乌龟棋 https://www.luogu.org/problemnew/show/P1541

    1   FOR(i,0,c[1]) FOR(j,0,c[2]) FOR(k,0,c[3]) FOR(l,0,c[4])
    2     {
    3         if(j) f[j][k][l]=max(f[j][k][l],f[j-1][k][l]);
    4         if(k) f[j][k][l]=max(f[j][k][l],f[j][k-1][l]);
    5         if(l) f[j][k][l]=max(f[j][k][l],f[j][k][l-1]);
    6         f[j][k][l]+=a[i+(j<<1)+k+(k<<1)+(l<<2)];
    7     }
    8     printf("%d",f[c[2]][c[3]][c[4]]);

    P1854 花店橱窗布置 https://www.luogu.org/problemnew/show/P1854

     1 void scan()
     2 {
     3     scanf("%d%d",&n,&m);
     4     FOR(i,1,n) FOR(j,1,m) scanf("%d",&a[i][j]);
     5     memset(f,-8,sizeof(f));
     6     FOR(i,0,n+1)f[i][0]=0;
     7 }
     8 
     9 void dp()
    10 {
    11     FOR(i,1,m) FOR(j,1,n)
    12     {
    13         //choose
    14         f[i][j]=f[i-1][j],d1[i][j]=i-1,d2[i][j]=j;
    15         //do not choose
    16         if(f[i-1][j-1]+a[j][i]>f[i][j])
    17             f[i][j]=f[i-1][j-1]+a[j][i],
    18             d1[i][j]=i-1,d2[i][j]=j-1,flag[i][j]=1;
    19     }
    20 }
    21 
    22 void findpath(int i,int j)
    23 {
    24     if(i==0||j==0) return;
    25     if(flag[i][j])FOR(ii,d1[i][j]+1,i) fl[ii]=j;
    26     findpath(d1[i][j],d2[i][j]);
    27 }
    28 
    29 void print()
    30 {
    31     printf("%d
    ",f[m][n]);
    32     findpath(m,n);
    33     FOR(i,1,m) vase[fl[i]]=i;
    34     FOR(i,1,n) printf("%d ",vase[i]);
    35 }

    poj1952 BUY LOW, BUY LOWER http://poj.org/problem?id=1952

     1 void scan()
     2 {
     3     n=rd();a[0]=2e9;d[0]=1;
     4     FOR(i,1,n) a[i]=rd();
     5 }
     6 
     7 void dp()
     8 {
     9     FOR(i,1,n) 
    10     {
    11         ll ans=-1;
    12         For(j,i-1,0) if(a[j]>a[i]) gmax(ans,f[j]);
    13         f[i]=ans+1;
    14         For(j,i-1,0) 
    15         {
    16             if(a[j]>a[i]&&f[j]==ans) d[i]+=d[j];
    17             else if(a[i]==a[j]&&f[i]==f[j]) break;
    18         }
    19         
    20     }
    21 }
    22 
    23 void print()
    24 {
    25     ll ans=0,num;FOR(i,1,n) 
    26     if(ans<f[i]){ans=f[i];num=d[i];}
    27     else if(ans==f[i]) num+=d[i];
    28     printf("%lld %lld",ans,num);
    29 }

    luogu SP33 TRIP - Trip https://www.luogu.org/problemnew/show/SP33

     1 const int N=82;
     2 char s1[N],s2[N];
     3 int f[N][N],d1[N][26],d2[N][26];
     4 vector < string > s;
     5 int n,m;
     6 
     7 void create(int a1,int a2,int l,string ss)
     8 {
     9     if(l==0) {s.push_back(ss);return;}
    10     FOR(i,0,25) if(f[d1[a1][i]][d2[a2][i]]==l)
    11         create(d1[a1][i]-1,d2[a2][i]-1,l-1,(char)('a'+i)+ss);
    12 }
    13 
    14 void scan()
    15 {
    16     memset(s1,'',sizeof(s1));
    17     memset(s2,'',sizeof(s2));
    18     memset(f,0,sizeof(f));
    19     memset(d1,0,sizeof(d1));
    20     memset(d2,0,sizeof(d2));
    21     s.clear();
    22     scanf("%s",s1+1);scanf("%s",s2+1);
    23     n=strlen(s1+1),m=strlen(s2+1);
    24 }
    25 
    26 void dp()
    27 {
    28     FOR(i,1,n) FOR(j,1,m)
    29     {
    30         if(s1[i]==s2[j]) gmax(f[i][j],f[i-1][j-1]+1);
    31         gmax3(f[i][j],f[i-1][j],f[i][j-1]);
    32     }
    33     FOR(i,1,n) FOR(j,0,25)
    34         if(s1[i]-'a'==j) d1[i][j]=i;
    35         else d1[i][j]=d1[i-1][j];
    36     FOR(i,1,m) FOR(j,0,25)
    37         if(s2[i]-'a'==j) d2[i][j]=i;
    38         else d2[i][j]=d2[i-1][j];
    39     create(n,m,f[n][m],"");
    40 }
    41 
    42 void print()
    43 {
    44     sort(s.begin() , s.end());
    45     FOR(i,0,s.size()-1) cout<<s[i]<<endl;
    46     printf("
    ");
    47 }
  • 相关阅读:
    Java 高级文件处理
    drf10
    drf9
    drf8
    drf7
    drf6
    drf5
    drf4
    drf3
    drf2
  • 原文地址:https://www.cnblogs.com/universeplayer/p/10660009.html
Copyright © 2020-2023  润新知