最长上升子序列 记忆化讲解

来源:互联网 发布:淘宝黑搜白搜的区别 编辑:程序博客网 时间:2024/06/05 05:01

n!正向搜索

#include<iostream>#include<cstdio>using namespace std;int a[5000],n,cnt,m,k,cu[5000],x;bool b[5000];void search(int s,int now,int m)//最长的值,上一个存下来的数字大小 {    for(int i=m;i<=n+1;i++)    {        if(i==n+1)        {            if(s>cnt) cnt=s;            return;        }        if(!b[i] && a[i]>now)        {            b[i]=1;            cu[s]=a[i];            search(s+1,a[i],i+1);            b[i]=0;        }    }}int main(){    cin>>n;    for(int i=1;i<=n;i++) cin>>a[i];    if(n==0) {cout<<1<<endl;return 0;}    m=1;    search(0,-999,1);    cout<<cnt<<endl;    return 0;}
//动态规划是求解最优问题//这道题是动态规划的前身 //input://7//1 7 3 5 9 4 8//output://4#include<iostream>#include<cstdio>using namespace std;int a[105],pr[105];int pre(int now){    if(pr[now]==1) return 1;    int maxn=0;    for(int i=1;i<now;i++)//如果在该位置之前的数字有比它小的 且为一个长度最大的子序列     {        int pe=pre(i);//希望你能感觉到这里有重复计算的嫌疑         if(a[i]<a[now] && pe>=maxn )        {            maxn=pe;            }       }    return maxn+1;//把当前的数加上} int main(){    int n;cin>>n;    for(int i=1;i<=n;i++)cin>>a[i];    for(int j=1;j<=n;j++)//求子序列中能成为首位的数字     {        int flag=0;        for(int i=1;i<j;i++)        {            if(a[i]<a[j]) flag=1;        }        if(flag==0) pr[j]=1;    }//  //  for(int i=1;i<=n;i++)//      if(pr[i]==1)//          cout<<i<<" ";    int mx=0;    for(int i=1;i<=n;i++)    {        pr[i]=pre(i);        if(pr[i]>mx)            mx=pr[i];    }    cout<<mx<<endl;}
//动态规划是求解最优问题#include<iostream>#include<cstdio>using namespace std;int a[105],pr[105];int pre(int now){    if(pr[now]) return pr[now];//记忆化搜索要素3:已经求过的就不在求了     int maxn=0;    for(int i=1;i<now;i++)//如果在该位置之前的数字有比它小的 且为一个长度最大的子序列     {        int pe=pre(i);        if(a[i]<a[now] && pe>=maxn )        {            maxn=pe;            }       }    pr[now]=maxn+1;//记忆化搜索1要素:先保存(这一步),后返回(下一步)     return pr[now];//记忆化搜索要素2:后返回 } int main(){    int n;cin>>n;    for(int i=1;i<=n;i++)cin>>a[i];    for(int j=1;j<=n;j++)//求子序列中能成为首位的数字     {        int flag=0;        for(int i=1;i<j;i++)        {            if(a[i]<a[j]) flag=1;        }        if(flag==0) pr[j]=1;    }//  //  for(int i=1;i<=n;i++)//      if(pr[i]==1)//          cout<<i<<" ";    int mx=0;    for(int i=1;i<=n;i++)    {        pr[i]=pre(i);        if(pr[i]>mx)            mx=pr[i];    }    cout<<mx<<endl;}
原创粉丝点击