zoukankan      html  css  js  c++  java
  • dp 入门

    1.HDU 1003

    求最长连续相加的和。

    dp[i]=max(a[i],dp[i-1]+a[i]);

    dp[i]表示以 i 结尾的最大值。

    再开/个strat去标记从哪里开始。

    #include <iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int dp[100010];
    int strat[100010];
    int a[100010];
    int main()
    {
       int t;
       scanf("%d",&t);
       int k=0;
       while(t--)
       {
           k++;
           int n;
           scanf("%d",&n);
           for(int i=0;i<n;i++)
           {
               scanf("%d",&a[i]);
           }
           memset(dp,0,sizeof dp);
           memset(strat,0,sizeof dp);
           dp[0]=a[0];
           strat[0]=0;
           int max=a[0];
           int pp=0;
           for(int i=1;i<n;i++)
           {
               if(a[i]>a[i]+dp[i-1])
               {
                 dp[i]=a[i];
                 strat[i]=i;
               }
               else
               {
                   dp[i]=dp[i-1]+a[i];
                   strat[i]=strat[i-1];
               }
               if(max<dp[i])
               {
                  max=dp[i];
                  pp=i;
               }
    
           }
           printf("Case %d:
    ",k);
           printf("%d %d %d
    ",max,strat[pp]+1,pp+1);
            if(t) printf("
    ");
    
    
    
    
       }
        return 0;
    }

     2.hdu 1087

    求最长上升序列的和;

    dp[i]=max(dp[j])+a[i];   a[j]<a[i];  

    #include <iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int dp[1005];
    int a[1005];
    int main()
    {
       int n;
       while(~scanf("%d",&n))
       {
           if(n==0)
            break;
           for(int i=0;i<n;i++)
           {
               scanf("%d",&a[i]);
           }
           memset(dp,0,sizeof dp);
            dp[0]=a[0];
           for(int i=1;i<n;i++)
           {
                int MAX=0;
              for(int j=0;j<i;j++)
              {
                 
                if(a[i]>a[j])
                {
                    MAX=max(MAX,dp[j]);
                }
              }
             dp[i]=MAX+a[i];
           }
           int t=0;
           for(int i=0;i<n;i++)
           {
               t=max(t,dp[i]);
           }
           cout<<t<<endl;
    
       }
        return 0;
    }

    3.HDU 1159  最长公共子序列

    dp[i][j]=dp[i-1][j-1]+1   a[i]==b[j]

    dp[i][j]=max(dp[i][j-1],dp[i-1][j]);

    读入是0 开始。计数的时候 从1开始。

    #include <iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int dp[1005][1005];
    char a[1005];
    char b[1005];
    int main()
    {
        while(cin>>a>>b)
        {
            int t1=strlen(a);
            int t2=strlen(b);
            memset(dp,0,sizeof dp);
            for(int i=1;i<=t1;i++)
            for(int j=1;j<=t2;j++)
            {
    
                if(a[i-1]==b[j-1])
                dp[i][j]=dp[i-1][j-1]+1;
                else
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
    
            }
          cout<<dp[t1][t2]<<endl;
    }
    
        return 0;
    }

     4.hdu-1160

    最长上升子序列加路径

    DP[i]表示i结尾的最长数目;

    自己加一个 0 0break 测试一下

    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    struct node
    {
        int w;
        int v;
        int no;
    }mice[1000];
    bool cmp(node a,node b)
    {
          if(a.w==b.w)
        return a.v<b.v;//最开始这里没有排一直出来5。因为体重一样的速度也在排。但是速度从小到大就不会被记录
        return a.w<b.w;
    }
    int pre[1000];
    int dp[1000];
    int main()
    {
        int a,b;
        int k=0;
        while(cin>>a>>b)
        {
             mice[k].w=a;
             mice[k].v=b;
             mice[k].no=k+1;
             k++;
        }
        sort(mice,mice+k,cmp);
        memset(pre,-1,sizeof pre);
       for(int i=0;i<k;i++)
       {
        dp[i]=1;
       }
        int mx=0,p=-1;
       for(int i = 0; i < k; i++)
        {
    
        for(int j = 0; j < i; j++)
        {
                 if( mice[j].v > mice[i].v)
                 {
                    if(dp[j]+1 > dp[i])
                    {
                        dp[i] = dp[j]+1;
                           pre[i] = j;
                     }
                 }
        }
    
            if(dp[i]>mx)
            {
                mx=dp[i];
                p=i;
            }
    
        }
        cout<<mx<<endl;
        int res[10000];
        int i=1;
        while(p!=-1)
        {
        res[i++]=mice[p].no;
        p=pre[p];
        }
        i--;
         for(;i>=1;i--)
            cout<<res[i]<<endl;
    
        return 0;
    }

     5.hdu-1176

    这题详细写了。

    dp[0][i]= dp[0][i]+max(dp[0][i+1],dp[1][i+1]);
    dp[j][i]=dp[j][i]+max(dp[j-1][i+1],max(dp[j][i+1],dp[j+1][i+1]));
    dp[10][i]= dp[10][i]+max(dp[10][i+1],dp[9][i+1]);
    #include<iostream>
    #include<algorithm>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int dp[11][100005];//i表示时间,j表示位子
    int main()
    {
        int n;
        int t,p;
        while(~scanf("%d",&n)&&n)
        {
            int mx=0;
           memset(dp,0,sizeof dp);
           for(int i=0;i<n;i++)
           {
             scanf("%d%d",&p,&t);
             dp[p][t]++;
             mx=max(mx,t);
           }
           for(int i=mx-1;i>=0;i--)
           {
               dp[0][i]= dp[0][i]+max(dp[0][i+1],dp[1][i+1]);
               for(int j=1;j<10;j++)
               {
                   dp[j][i]=dp[j][i]+max(dp[j-1][i+1],max(dp[j][i+1],dp[j+1][i+1]));
               }
               dp[10][i]= dp[10][i]+max(dp[10][i+1],dp[9][i+1]);
           }
         cout<<dp[5][0]<<endl;
    
    
        }
        return 0;
    }
  • 相关阅读:
    SpringBoot Shiro 配置自定义密码加密器
    SpringBoot Druid 配置详解
    UOJ #164. 【清华集训2015】V | 线段树
    BZOJ 4552 [Tjoi2016&Heoi2016]排序 | 二分答案 线段树
    51nod 1462 树据结构 | 树链剖分 矩阵乘法
    BZOJ 3503 [CQOI2014]和谐矩阵
    BZOJ 4004 [JLOI2015]装备购买 | 线性基
    BZOJ 4785 [Zjoi2017]树状数组 | 二维线段树
    LOJ #2145. 「SHOI2017」分手是祝愿
    LOJ #2141. 「SHOI2017」期末考试
  • 原文地址:https://www.cnblogs.com/2014slx/p/7289416.html
Copyright © 2011-2022 走看看