单调递增最长子序列nyoj17

来源:互联网 发布:淘宝发布宝贝主图尺寸 编辑:程序博客网 时间:2024/06/06 05:38

单调递增最长子序列为动态规划比较简单而且比较有代表性的一道最长子序列题目,其中的状态转换方程较为容易理解。

for(i=0;i<len;i++){count[i]=1;for(j=0;j<i;j++){if(s[i]>s[j]&&count[j]+1>count[i])count[i]=count[j]+1;}
       把count【i】赋值为1,来作为备忘录,循环内的循环表示着:第【i】个字母依次与0到i个字母进行比较,同时与count代表的子序列长度做比较,

比如输入abecd:

i=0时,循环直接跳出。

i=1时,进行依次循环,b与a进行比较,符合if条件,count【1】+1=2大于了count【2】,那么此时,count【1】=2。

i=2时,再进行依次比较,e与a比较,符合,这是count【2】=2,然后再与b比较,因为此时count【2】已经等于2,所以加1后还可以超过count【1】

所以,此时count【2】=count【1】+1=3;

i=3时,进行依次比较,c与a比较,count【3】=2;c与b比较,count【3】=3;c与e比较,c<e直接跳出循环,结束时,count【3】=3;

i=4时,这是最后一步了,可以从上知道count【2】与count【3】同为3,所以这是决定性的一步,①d与a比较,count【4】=2;②d与b比较 。count【4】=3;③d与e比较,不符合if条件,跳出,④d与c比较,还可以再进一步,count【4】=4.

所以,最长的count【i】是count【4】=4。也就是最终答案。   


代码:

#include<iostream>#include<string>using namespace std;int main(){string s;int count[10005];int i,j,N,len,ch,k;cin>>N;while(N--){cin>>s;len=s.length();k=1;for(i=0;i<len;i++){count[i]=1;for(j=0;j<i;j++)//状态转换方程 {if(s[i]>s[j]&&count[j]+1>count[i])//每一个数,依次与前面比较,而且与每个数存的count[i]比较,如果count能增加,那么就可以继续加1 count[i]=count[j]+1;//存储每个字母前面的最长子序列 }if(k<count[i])//可直接进行,也可在最后排序 k=count[i];}cout<<k<<endl;}return 0;}


希望能够帮助到你。