这道题采用动态规划思想,划分状态,确立每一个状态,找出状态转移方程。以最后一行数据stripe[k]为参考,划分状态,stripe[k+1]为第k+1个状态,状态转移方程可以描述为如果state[k+1]=max{state[i]+1|stripe[k+1]在给定顺序order[i]后面,i在1到k之间},然后可以给出下面程序,程序提交最后一个点没有通过,继续找找原因
#include <iostream>
using namespace std;
int stripe[10001];
int state[10001];//用来存储中间第k个状态的长度
int indexNum[10001];//用来存储stripe每个数字处于order中第几个
int findIndex(int num,int a[],int len){
int index;
for(int i=1;i<=len;i++){
if(num==a[i])
return i;
}
return -1;
}
int main(){
int N,M,order[201],L;
cin>>N;
cin>>M;
for(int i=1;i<=M;i++)
cin>>order[i];
cin>>L;
for(int i=1;i<=L;i++)
cin>>stripe[i];
if(L<1||M<1){
cout<<0;
return 0;
}
else{
if(stripe[1]==order[1])
state[1]=1;
else
state[1]=0;
}
for(int i=1;i<=L;i++)
indexNum[i]=findIndex(stripe[i],order,M);//先存储起来,方便下面查找
for(int i=2;i<=L;i++){//计算以i结尾的话最长长度
int longest=-1;//存储每一个数字结尾的状态的最长数列
for(int j=1;j<i;j++){//计算从j开始到i结尾最长长度
int jIndex=indexNum[j];
int iIndex=indexNum[i];
if((jIndex<=iIndex)&&iIndex!=-1){//如果第i个数刚好是前面某一个数的后面一个,或者刚好是第一个匹配的
if(state[i]<state[j]+1&&longest<state[j]+1){//新加入一个数字比原来长度大
longest=state[j]+1;
state[i]=longest;
}
}
}
}
cout<<state[L];
return 0;
}