经典Dp题目

来源:互联网 发布:用excel预测数据 编辑:程序博客网 时间:2024/05/20 23:03

1. Hdu   Max  sum :

题意:  最大连续和,但要输出这个序列的起始和末尾;

     两种线性时间算法:   1,前缀和       S[j]--S[i-1]:     S[i-1]最小

                                          2,Dp   状态转移方程  :  S[i]=Max(0, S[i-1])+A[i];

 #include<iostream>#define N 100010using namespace std;int a[N],d[N];int main(){    #ifndef ONLINE_JUDGE    freopen("in.cpp","r",stdin);#endif // ONLINE_JUDGE    int test,n,i,Max,k,f,e;    cin>>test;    k=0;    while(test--)    {        cin>>n;        for(i=1;i<=n;i++)            cin>>a[i];        d[0]=0;        for(int i=1;i<=n;i++)            d[i]=d[i-1]+a[i];        Max=-9999;        int Min=d[0];        for(int i=1;i<=n;i++)        {            if(d[i]-Min>Max)  { Max=d[i]-Min; e=i;}            if(d[i]<Min)   Min=d[i];        }        f=e;        int t=0;        for(int i=e;i>0;i--)        {            t+=a[i];            if(t==Max)  f=i;        }        printf("Case %d:\n",++k);        printf("%d %d %d\n",Max,f,e);        if(test) cout<<endl;    }    return 0;}

2. poj   2533  Longest Ordered Subsequence

最长上升子序列:   状态转移方程: Dp[i]== max(dp[j] ( i<j.A[i]<A[j] )) +1;

const int maxn=1010;using namespace std;int  dp[maxn];int A[maxn];int main(){    #ifndef ONLINE_JUDGE    freopen("in.cpp","r",stdin);#endif // ONLINE_JUDGE    int n;    while(scanf("%d",&n)!=EOF)     {          for(int i=1;i<=n;i++)            scanf("%d",&A[i]);           dp[1]=1;           int Max=1;           int m;         for(int i=2;i<=n;i++)         {             m=0;            for(int j=1;j<i;j++)            {                if(A[j]<A[i]&&dp[j]>=m)                    m=dp[j];            }            dp[i]=m+1;            if(dp[i]>Max)  Max=dp[i];         }         printf("%d\n",Max);     }    return 0;}

 nlogn :

#define MP make_pair#define PB push_back#define AA first#define BB second#define BG begin()#define ED end()#define SZ size()int a[100005];int main(){     #ifndef ONLINE_JUDGE    freopen("in.cpp","r",stdin);    #endif // ONLINE_JUDGE    int i,n,j,k,_T;        while(scanf("%d",&n)==1){        for(i=1;i<=n;i++)scanf("%d",&a[i]);        vector<int>L;        for(i=1;i<=n;i++){            int id=std::lower_bound(L.OP,L.ED,a[i])-L.OP;            if(id==L.SZ)L.PB(a[i]);            else L[id]=a[i];        }        printf("%d\n",L.SZ);        }    return 0;}


       uva  10635   Prince and Princess

  用nlogn 解决最长递增子序列。 

  将求最长公共子序列转化为求最长递增子序列

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<map>#include<set>#include<cmath>#include<string>#include<algorithm>using namespace std;const int maxn=65000;const int inf=1000000000;int A[maxn];int B[maxn];int C[maxn];int D[maxn];int main(){    #ifndef ONLINE_JUDGE    freopen("in.cpp","r",stdin);#endif // ONLINE_JUDGE    int t;    cin>>t;    int Cas=0;    while(t--)    {        int n,p,q;        scanf("%d%d%d",&n,&p,&q);        int x;        memset(A,0,sizeof(A));        for(int i=1;i<=p+1;i++)            {                scanf("%d",&x);                A[x]=i;            }        int y;        int s=0;        for(int i=1;i<=q+1;i++)            {                scanf("%d",&y);                if(A[y])  B[s++]=A[y];            }         for(int i=0;i<=s;i++)  C[i]=inf;         int ans=0,k;         for(int i=0;i<s;i++)         {              k=lower_bound(C+1,C+s,B[i])-C;             D[i]=k;             C[k]=B[i];             ans=max(ans,D[i]);         }         printf("Case %d: %d\n",++Cas,ans);    }}





3. poj   1458   Longest Common Subsequence

最长公共子序列: 

状态转移: if(str1[i-1]==str2[j-1]) dp[i][j]=dp[i-1][j-1]+1;

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

const int maxn=305;string str1,str2 ;int dp[maxn][maxn];int main(){#ifndef ONLINE_JUDGE    freopen("in.cpp","r",stdin);#endif // ONLINE_JUDGE    int h1,h2;    while(cin>>str1>>str2)    {        h1=str1.size();        h2=str2.size();        memset(dp,0,sizeof(dp));        for(int i=1; i<=h1; i++)        {            for(int j=1; j<=h2; j++)            {                if(str1[i-1]==str2[j-1])                     dp[i][j]=dp[i-1][j-1]+1;                else                {                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);                }            }        }        printf("%d\n",dp[h1][h2]);        getchar();    }    return 0;}</span>


0 0