T1:
给出一个由数字(‘0’-‘9’)构成的字符串。我们说一个子序列是好的,如果他的每一位都是 1、8、0、7 ,并且这四个数字按照这种顺序出现,且每个数字都出现至少一次(111888888880000007 是好的,而 1087 不是)。请求出最大的好的子序列的长度。
输入
1800777700088888000777
输出
13子序列:1800000000777
一定要先int len=strlen(st+1) 再for,如果for(int i=1;i<=strlen(st+1);++i)会超时。
简单的动规
不过要memset(f,128,sizeof(f))
memset(f,0,sizeof(f))
全为0
memset(f,-1,sizeof(f)) 全为-1
memset(f,127,sizeof(f)) 极大2139062143 memset(f,128,sizeof(f)) 极小-2139062143
memset(f,1,sizeof(f)) ...不是全为1
我的程序
#include<bits/stdc++.h>
using namespace std;
char st[1000005];
int a[1000005],f[1000005][5];
int tot,t[1000005];
int main(){
// freopen("1807.in","r",stdin);
// freopen("1807.out","w",stdout);
memset(t,0,sizeof(t));
memset(f,128,sizeof(f));
gets(st+1);
int len=strlen(st+1);
for(int i=1;i<=len;++i){
if(st[i]==st[i-1]){
t[tot]++;
}
else {
tot++,t[tot]++;
if(st[i]=='1') a[tot]=1;
if(st[i]=='8') a[tot]=2;
if(st[i]=='0') a[tot]=3;
if(st[i]=='7') a[tot]=4;
}
}
f[0][0]=0;
for(int i=1;i<=tot;++i){
f[i][0]=f[i-1][0];
f[i][1]=f[i-1][1];
f[i][2]=f[i-1][2];
f[i][3]=f[i-1][3];
f[i][4]=f[i-1][4];
if(a[i]==1) f[i][1]=max(f[i-1][0],f[i][1])+t[i];
if(a[i]==2) f[i][2]=max(f[i-1][1],f[i][2])+t[i];
if(a[i]==3) f[i][3]=max(f[i-1][2],f[i][3])+t[i];
if(a[i]==4) f[i][4]=max(f[i-1][3],f[i][4])+t[i];
}
cout<<max(0,f[tot][4])<<endl;
}
更优
#include<bits/stdc++.h>
using namespace std;
char st[1000005];
int a[1000005],f[5];
int main(){
memset(f,128,sizeof(f));
gets(st+1);
int len=strlen(st+1);
for(int i=1;i<=len;++i){
if(st[i]=='1') f[1]=max(f[1],0)+1;
if(st[i]=='8') f[2]=max(f[2],f[1])+1;
if(st[i]=='0') f[3]=max(f[3],f[2])+1;
if(st[i]=='7') f[4]=max(f[4],f[3])+1;
}
cout<<max(0,f[4])<<endl; }