基础DP(4)

  • 最长递增子序列(LIS)

http://120.78.128.11/Problem.jsp?pid=1388

http://acm.hdu.edu.cn/showproblem.php?pid=1257

 

最长递增子序列,例如X={5,6,7,4,2,8,3},它的最长递增子序列为{5,6,7,8},长度为4。

 

题目上是需要求单调递减子序列最少有多少个,按照LIS的思想,只用把递增改为递减即可。

定义dp[i],用它来表示以第i个数为结尾的最长递增子序列的长度,得到状态方程:dp[i]=max(0,dp[j])+1。(0<j<i,Aj<Ai)

代码1:

#include<stdio.h>
#include<algorithm>
using namespace std;
int n,cnt;
int a[10005],b[10005];
int main(void)
{
    while(~scanf("%d",&n)){
        cnt=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            b[i]=1;
            for(int j=1;j<=i;j++){
                if(a[j]<a[i])
                b[i]=max(b[i],b[j]+1);
                cnt=max(cnt,b[i]);
            }
        }
        printf("%d\n",cnt);
    }
}

 

 

代码2:

#include<bits/stdc++.h>
using namespace std;

const int MAXN=10000;
int n,high[MAXN];

int LIS(){
    int cnt=1;
    int dp[MAXN];
    dp[1]=1;
    for(int i=2;i<=n;i++){
        int max=0;
        for(int j=1;j<i;j++){
            if(dp[j]>max&&high[j]<high[i])
            max=dp[j];
        }
        dp[i]=max+1;
        if(dp[i]>cnt)
        cnt=dp[i];
    }
        return cnt;
}

int main()
{
    while(cin>>n){
        for(int i=1;i<=n;i++){
            cin>>high[i];
        }
        cout<<LIS()<<endl;
    }
    return 0;
}

 

要求输出具体方案时,同样可以用滚动数组减少空间复杂度,和0/1背包相同。

 码一点基础DP题~

背包:

http://acm.hdu.edu.cn/showproblem.php?pid=2159

http://acm.hdu.edu.cn/showproblem.php?pid=2844

http://acm.hdu.edu.cn/showproblem.php?pid=3092

http://poj.org/problem?id=1015

http://poj.org/problem?id=1170

LIS:

http://acm.hdu.edu.cn/showproblem.php?pid=1003

http://acm.hdu.edu.cn/showproblem.php?pid=1087

http://acm.hdu.edu.cn/showproblem.php?pid=4352

http://poj.org/problem?id=1239

LCS:

http://acm.hdu.edu.cn/showproblem.php?pid=1503

http://poj.org/problem?id=1080

 

EOF

 

posted @ 2021-01-26 22:47  Untergehen  阅读(68)  评论(0编辑  收藏  举报