C++ & Java——1807——动态规划

9 篇文章 0 订阅

题目描述

给出一个由数字(‘0’-‘9’)构成的字符串。我们说一个子序列是好的,如果他的每一位都是 1、8、0、7 ,并且这四个数字按照这种顺序出现,且每个数字都出现至少一次(111888888880000007 是好的,而 1087 不是)。请求出最大的好的子序列的长度。

输入格式

输入唯一一行一个字符串。

输出格式

一行一个整数表示答案。

样例数据 1

输入

1800777700088888000777

输出

13

备注

【数据范围】
对 30% 的输入数据 :字符串长度≤100 ;
对 100% 的输入数据 :字符串长度≤1000000 。

30%:枚举最后一个1,最后一个0,最后一个8的位置,然后扫一下第一段中有几个1,
第二段中有几个0,第三段中有几个8,最后一段中有几个7,用他们的和更新最大值,复
杂度O(n^4); 
100%:dp,用f[i][j]表示做了前面i位,然后当前用到了第j个数字(分别映射1、0、
8、7),然后进行简单的转移,最后f[n][4]就是答案,复杂度O(n);

#include<string.h>
#include<string.h>
#include<iostream>
using namespace std;
int f[5],n;
char s[1000001];
int main()
{
	gets(s);
	n=strlen(s);
    memset(f,128,sizeof(f));
	f[4]=0;
	for(int i=1;i<=n;++i)
    {
		if(s[i-1]=='1') f[0]=max(f[0],f[4])+1;
		if(s[i-1]=='8') f[1]=max(f[0],f[1])+1;
		if(s[i-1]=='0') f[2]=max(f[2],f[1])+1;
		if(s[i-1]=='7') f[3]=max(f[3],f[2])+1;
	}
	printf("%d\n",max(f[3],0));
	return 0;
}


import java.util.*;    
import java.lang.*;  
public class Main      
{     
	static int [] f=new int [5];
	static int n; 
	public static void main(String[] args)      
	{      
	    Scanner input = new Scanner(System.in);    
	    String s=input.nextLine();
	    n=s.length();
	    Arrays.fill(f,-1000000);
	    f[4]=0;
		for(int i=1;i<=n;++i)
	    {
	    	if(s.charAt(i-1)=='1') f[0]=Math.max(f[0],f[4])+1;
			if(s.charAt(i-1)=='8') f[1]=Math.max(f[0],f[1])+1;
			if(s.charAt(i-1)=='0') f[2]=Math.max(f[2],f[1])+1;
			if(s.charAt(i-1)=='7') f[3]=Math.max(f[3],f[2])+1;
	    }
	    if(f[3]<0) f[3]=0;
	    System.out.println(f[3]);    
	}      
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值