• 第六周 6.21-6.27


    6.21

    最长不下降子序列

    LIS有nlgn的算法。纯学dp。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <algorithm>
     4 using namespace std;
     5 int num[5005],d[5005];
     6 
     7 int main(void)
     8 {
     9     int n; cin>>n;
    10     for(int i=0;i<n;i++) scanf("%d",num+i);
    11     for(int i=0;i<n;i++)
    12     {
    13         d[i]=1;
    14         for(int j=0;j<i;j++)
    15             if(num[j]<=num[i]) d[i]=max(d[i],d[j]+1);
    16     }
    17     int ans=0;
    18     for(int i=0;i<n;i++) ans=max(ans,d[i]);
    19     printf("%d
    ",ans);
    20     return 0;
    21 }
    Aguin

    矩形嵌套

    紫薯题。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <algorithm>
     4 using namespace std;
     5 int dp[1005];
     6 
     7 struct node
     8 {
     9     int a,b;
    10 }edge[1005];
    11 
    12 bool cmp(node x,node y)
    13 {
    14     if(x.a!=y.a) return x.a<y.a;
    15     else return x.b<y.b;
    16 }
    17 
    18 int main(void)
    19 {
    20     int N;cin>>N;
    21     while(N--)
    22     {
    23         int n;scanf("%d",&n);
    24         for(int i=0;i<n;i++)
    25         {
    26             scanf("%d%d",&edge[i].a,&edge[i].b);
    27             if(edge[i].a<edge[i].b)
    28             {
    29                 int t=edge[i].a;
    30                 edge[i].a=edge[i].b;
    31                 edge[i].b=t;
    32             }
    33         }
    34         sort(edge,edge+n,cmp);
    35         for(int i=0;i<n;i++)
    36         {
    37             dp[i]=1;
    38             for(int j=0;j<i;j++)
    39                 if(edge[j].a<edge[i].a&&edge[j].b<edge[i].b) dp[i]=max(dp[i],dp[j]+1);
    40         }
    41         int ans=0;
    42         for(int i=0;i<n;i++) ans=max(ans,dp[i]);
    43         printf("%d
    ",ans);
    44     }
    45     return 0;
    46 }
    Aguin

    6.22

    UVA 103 Stacking Boxes

    升级版的n维矩形。打印一个路径就好。然而数据太亲民。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <cstring>
     4 # include <algorithm>
     5 using namespace std;
     6 int k,n,dp[30],G[30][30];
     7 
     8 struct BOX
     9 {
    10     int no,edge[10];
    11 }box[30];
    12 
    13 bool cmp(BOX a,BOX b)
    14 {
    15     for(int i=0;i<n;i++)
    16         if(a.edge[i]!=b.edge[i]) return a.edge[i]<b.edge[i];
    17     return a.edge[n-1]<b.edge[n-1];
    18 }
    19 
    20 void ans_print(int pos)
    21 {
    22     if(dp[pos]==1) printf("%d",box[pos].no);
    23     else
    24     {
    25         for(int i=0;i<pos;i++)
    26             if(G[i][pos]&&dp[i]==dp[pos]-1)
    27             {
    28                 ans_print(i);
    29                 break;
    30             }
    31         printf(" %d",box[pos].no);
    32     }
    33     return;
    34 }
    35 
    36 int main(void)
    37 {
    38     while((scanf("%d%d",&k,&n))!=EOF)
    39     {
    40         memset(G,0,sizeof(G));
    41         for(int i=0;i<k;i++)
    42         {
    43             for(int j=0;j<n;j++)
    44                 scanf("%d",&box[i].edge[j]);
    45             box[i].no=i+1;
    46             sort(box[i].edge,box[i].edge+n);
    47         }
    48         sort(box,box+k,cmp);
    49         for(int i=0;i<k;i++)
    50         {
    51             dp[i]=1;
    52             for(int j=0;j<i;j++)
    53             {
    54                 int ok=1;
    55                 for(int t=0;t<n;t++)
    56                     if(box[j].edge[t]>=box[i].edge[t]) {ok=0;break;}
    57                 if(ok) {G[j][i]=1; dp[i]=max(dp[i],dp[j]+1);}
    58             }
    59         }
    60         int ans=0,pos;
    61         for(int i=0;i<k;i++) if(dp[i]>ans) {ans=dp[i]; pos=i;}
    62         printf("%d
    ",ans);
    63         ans_print(pos);
    64         printf("
    ");
    65     }
    66     return 0;
    67 }
    Aguin

    6.23

    发觉自己对dp的理解就有问题。紫薯啃的不明白。

    文章也难找到合适的。

    有的过于抽象。实例又容易固化思维。

    P1084 数字三角形4

    稍微改了下就不会了。只能说没领会。

    往上往下dp。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <cstring>
     4 # include <algorithm>
     5 using namespace std;
     6 int n,x,y,num[26][26],d1[26][26],d2[26][26];
     7 
     8 int dp1(int i,int j)
     9 {
    10     if(d1[i][j]>=0) return d1[i][j];
    11     return d1[i][j]= ( (i==n)? num[i][j] : ( max(dp1(i+1,j),dp1(i+1,j+1))+num[i][j] ) );
    12 }
    13 
    14 int dp2(int i,int j)
    15 {
    16     if(d2[i][j]>=0) return d2[i][j];
    17     if(i==1) return d2[i][j]=num[i][j];
    18     int ans=num[i][j]+dp2(i-1,j);
    19     if(j-1>0) ans=max(ans,num[i][j]+dp2(i-1,j-1));
    20     return ans;
    21 }
    22 
    23 int main(void)
    24 {
    25     cin>>n;
    26     memset(d1,-1,sizeof(d1));
    27     memset(d2,-1,sizeof(d2));
    28     for(int i=1;i<=n;i++)
    29         for(int j=1;j<=i;j++)
    30             scanf("%d",&num[i][j]);
    31     scanf("%d%d",&x,&y);
    32     printf("%d
    ",dp1(x,y)+dp2(x,y)-num[x][y]);
    33     return 0;
    34 }
    Aguin

    P1004 滑雪

    题目没什么。代码丑。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <algorithm>
     4 using namespace std;
     5 # define X(i) (i/c+((i%c)?1:0))
     6 # define Y(i) ((i%c)?(i%c):c)
     7 # define ID(i,j) ((i-1)*c+j)
     8 int dp[10001],map[10001];
     9 
    10 struct node
    11 {
    12     int id,h;
    13 } G[10001];
    14 
    15 bool cmp(node a,node b)
    16 {
    17     return a.h>b.h;
    18 }
    19 
    20 int main(void)
    21 {
    22     int r,c; cin>>r>>c;
    23     for(int i=1;i<=r*c;i++)
    24     {
    25         scanf("%d",&G[i].h);
    26         G[i].id=i;
    27     }
    28     sort(G+1,G+r*c+1,cmp);
    29     for(int i=1;i<=r*c;i++) map[G[i].id]=i;
    30     int ans=0;
    31     for(int i=1;i<=r*c;i++)
    32     {
    33         int no=G[i].id,x=X(no),y=Y(no),H=G[i].h;
    34         dp[no]=1;
    35         if(x>1&&G[map[ID(x-1,y)]].h>H) dp[no]=max(dp[no],dp[G[map[ID(x-1,y)]].id]+1);
    36         if(y>1&&G[map[ID(x,y-1)]].h>H) dp[no]=max(dp[no],dp[G[map[ID(x,y-1)]].id]+1);
    37         if(x<r&&G[map[ID(x+1,y)]].h>H) dp[no]=max(dp[no],dp[G[map[ID(x+1,y)]].id]+1);
    38         if(y<c&&G[map[ID(x,y+1)]].h>H) dp[no]=max(dp[no],dp[G[map[ID(x,y+1)]].id]+1);
    39         ans=max(ans,dp[no]);
    40     }
    41     printf("%d
    ",ans);
    42     return 0;
    43 }
    Aguin

    6.24

    HDU 1231 最大连续子序列

     1 # include <iostream>
     2 # include <cstdio>
     3 using namespace std;
     4 int num[10005],dp[10005],head[10005];
     5 
     6 int main(void)
     7 {
     8     int K;
     9     while((scanf("%d",&K))!=EOF&&K)
    10     {
    11         for(int i=0;i<K;i++)
    12             scanf("%d",num+i);
    13         for(int i=0;i<K;i++)
    14             if(i&&dp[i-1]>0) {dp[i]=dp[i-1]+num[i];head[i]=head[i-1];}
    15             else {dp[i]=num[i];head[i]=num[i];}
    16         int sum=-1,pos;
    17         for(int i=0;i<K;i++)
    18             if(dp[i]>sum) {sum=dp[i];pos=i;}
    19         if(sum<0) printf("0 %d %d
    ",num[0],num[K-1]);
    20         else printf("%d %d %d
    ",sum,head[pos],num[pos]);
    21     }
    22     return 0;
    23 }
    Aguin

    最长公共子序列   LCS

    想不出来阿阿阿阿阿阿阿阿阿阿阿。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <algorithm>
     4 # include <cstring>
     5 using namespace std;
     6 char a[1005],b[1005];
     7 int F[1005][1005];
     8 
     9 int dp(int i,int j)
    10 {
    11     if(F[i][j]>=0) return F[i][j];
    12     if(i==0||j==0) return F[i][j]=0;
    13     if(a[i]==b[j]) return F[i][j]=dp(i-1,j-1)+1;
    14     return F[i][j]=max(dp(i,j-1),dp(i-1,j));
    15 }
    16 
    17 int main(void)
    18 {
    19     int N;cin>>N;
    20     while(N--)
    21     {
    22         memset(F,-1,sizeof(F));
    23         scanf("%s %s",a+1,b+1);
    24         printf("%d
    ",dp(strlen(a+1),strlen(b+1)));
    25     }
    26     return 0;
    27 }
    Aguin

    POJ 1050 To the Max

    二维最大连续子列。

    枚举了列的范围。在行求最大连续子列。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <algorithm>
     4 using namespace std;
     5 int sum[105][105]={0},dp[105][105][105];
     6 
     7 int main(void)
     8 {
     9     int N;
    10     while(cin>>N)
    11     {
    12         for(int i=1;i<=N;i++)
    13             for(int j=1;j<=N;j++)
    14             {
    15                 int x; scanf("%d",&x);
    16                 sum[i][j]=x;
    17                 if(j) sum[i][j]+=sum[i][j-1];
    18             }
    19         int ans=-2147483647;
    20         for(int i=1;i<=N;i++)
    21             for(int j=i;j<=N;j++)
    22                 for(int k=1;k<=N;k++)
    23                 {
    24                     if(i&&dp[i][j][k-1]>0) dp[i][j][k]=dp[i][j][k-1]+sum[k][j]-sum[k][i-1];
    25                     else dp[i][j][k]=sum[k][j]-sum[k][i-1];
    26                     ans=max(ans,dp[i][j][k]);
    27                 }
    28         printf("%d
    ",ans);
    29     }
    30     return 0;
    31 }
    Aguin

    6.25

    一个题没写完。明日补。

    6.26

    士兵杀敌(三)

    看DP的时候看见这个。

    咦?这难道不是线段树吗- -

    然而并没有update。于是可有更高效的算法。

    于是发现了解决RMQ问题的ST算法。

    之前有看见过ST。以为是什么高大上就没有看。

    看了一下发现和线段树的二分一样。就像每个点下面有一个不能update的树。

    预处理的时候至下而上的操作是DP。然后就可以O(1)query拉。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <cmath>
     4 # include <algorithm>
     5 using namespace std;
     6 # define maxn 100000+5
     7 int num[maxn],MAX[maxn][20],MIN[maxn][20];
     8 
     9 int main(void)
    10 {
    11     int N,Q;cin>>N>>Q;
    12     for(int i=1;i<=N;i++)
    13     {
    14         scanf("%d",num+i);
    15         MAX[i][0]=MIN[i][0]=num[i];    
    16     }
    17     for(int j=1;j<20;j++)
    18         for(int i=1;i<=N;i++)
    19             if(i+(1<<j)-1<=N)
    20             {
    21                 MAX[i][j]=max(MAX[i][j-1],MAX[i+(1<<j-1)][j-1]);
    22                 MIN[i][j]=min(MIN[i][j-1],MIN[i+(1<<j-1)][j-1]);
    23             }
    24     for(int i=0;i<Q;i++)
    25     {
    26         int m,n; scanf("%d%d",&m,&n);
    27         int k=(log(double(n-m+1))/log(2));
    28         int ans=max(MAX[m][k],MAX[n-(1<<k)+1][k])-min(MIN[m][k],MIN[n-(1<<k)+1][k]);
    29         printf("%d
    ",ans);
    30     }
    31     return 0;
    32 }
    Aguin

    6.27

    HDU 5266 pog loves szh III

    上上周BC一个题。LCA+ST。学了ST之后立马翻出了这题。

    中间还用到了dfs序。感觉处理的不是很棒。代码也丑。

    时限开的6s。2s跑完还行吧。1次AC开心。

     1 # pragma comment(linker, "/STACK:1024000000,1024000000")
     2 # include <iostream>
     3 # include <cstdio>
     4 # include <cstring>
     5 # include <vector>
     6 # include <algorithm>
     7 # include <cmath>
     8 using namespace std;
     9 # define maxn 300000+10
    10 # define CLR(x) memset(x,0,sizeof(x))
    11 int t,pa[maxn],ans[maxn],MAX[maxn][20],MIN[maxn][20];
    12 bool vis[maxn];
    13 vector <int> vec[maxn];
    14 vector < pair<int,int> > query[maxn];
    15 
    16 int fa(int x)
    17 {
    18     return pa[x]==x?x:pa[x]=fa(pa[x]);
    19 }
    20 
    21 struct node
    22 {
    23     int no,time;
    24 } T1[maxn],T2[maxn];
    25 
    26 void dfs(int i)
    27 {
    28     T1[i].no=i; T1[i].time=++t;
    29     MAX[i][0]=MIN[i][0]=t;
    30     for(int j=0;j<vec[i].size();j++)
    31         if(!T1[vec[i][j]].time) dfs(vec[i][j]);
    32     return;
    33 }
    34 
    35 bool cmp(node a,node b)
    36 {
    37     return a.time<b.time;
    38 }
    39 
    40 void LCA(int x)
    41 {
    42     for(int i=0;i<vec[x].size();i++)
    43         if(T2[vec[x][i]].time>T2[x].time)
    44         {
    45             LCA(T2[vec[x][i]].no);
    46             pa[T2[vec[x][i]].no]=x;
    47         }
    48     vis[x]=1;
    49     for(int i=0;i<query[x].size();i++)
    50     {
    51         int a=query[x][i].first,b=query[x][i].second;
    52         ans[a]=fa(b);
    53     }
    54     return;
    55 }
    56 
    57 int main(void)
    58 {
    59     int n;
    60     while(cin>>n)
    61     {
    62         CLR(vis); CLR(T1);
    63         for(int i=1;i<=n;i++)
    64         {
    65             pa[i]=i;
    66             vec[i].clear();
    67             query[i].clear();
    68         }
    69         for(int i=0;i<n-1;i++)
    70         {
    71             int b,c; scanf("%d%d",&b,&c);
    72             vec[b].push_back(c);
    73             vec[c].push_back(b);
    74         }
    75         t=0; dfs(1);
    76         memcpy(T2,T1,sizeof(T2));
    77         sort(T1+1,T1+1+n,cmp);
    78         for(int j=1;j<20;j++)
    79             for(int i=1;i<=n;i++)
    80                 if(i+(1<<j)-1<=n)
    81                 {
    82                     MAX[i][j]=max(MAX[i][j-1],MAX[i+(1<<j-1)][j-1]);
    83                     MIN[i][j]=min(MIN[i][j-1],MIN[i+(1<<j-1)][j-1]);
    84                 }
    85         int Q; scanf("%d",&Q);
    86         for(int i=0;i<Q;i++)
    87         {
    88             int L,R; scanf("%d%d",&L,&R);
    89             int k=(log(double(R-L+1))/log(2));
    90             int x=max(MAX[L][k],MAX[R-(1<<k)+1][k]);
    91             int y=min(MIN[L][k],MIN[R-(1<<k)+1][k]);
    92             query[T1[x].no].push_back(make_pair(i,T1[y].no));
    93         }
    94         LCA(1);
    95         for(int i=0;i<Q;i++) printf("%d
    ",ans[i]);
    96     }
    97     return 0;
    98 }
    Aguin
  • 相关阅读:
    心跳监控系统
    Mysql主从配置+读写分离(转)
    linux系统文件属性-硬连接、软连接
    巧用MySQL InnoDB引擎锁机制解决死锁问题(转)
    mysql数据库编码、字段编码、表编码 专题
    MySQL中select * for update锁表的问题(转)
    Android setTextColor无效_安卓setTextColor()的参数设置方式
    Android如何查看应用签名信息--微信平台开发应用的签名
    Android 生成keystore,两种方式
    MyEclipse + Maven开发Web工程的详细配置过程
  • 原文地址:https://www.cnblogs.com/Aguin/p/4591871.html
Copyright © 2020-2023  润新知