牛客21302题 被3整除的子序列

1 篇文章 0 订阅
1 篇文章 0 订阅

被3整除的子序列

题目
题目描述 
给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
答案对1e9+7取模
输入描述:
输入一个字符串,由数字构成,长度小于等于50
输出描述:
输出一个整数
示例1
输入
复制
132
输出
复制
3
示例2
输入
复制
9
输出
复制
1
示例3
输入
复制
333
输出
复制
7
示例4
输入
复制
123456
输出
复制
23
示例5
输入
复制
00
输出
复制
3
备注:
n为长度
子任务1: n <= 5
子任务2: n <= 20
子任务3: 无限制
思路

这个题是一个典型的动态规划问题,与背包问题类似

解决动态规划题我大致分为三个步骤:

  1. 找规律

  1. 转移方程

  1. 初始条件和边界情况

题解

首先分析题目,这个题的大致意思就是给一串数字,类似798,然后找出这个字串的所有子序列,相当于就是{7,8,9,78,79,89,798},然后找出这些字串中能被3整除的数量,798返回的就是3

然后找到第一个规律,79的子串是{7,9,79},在后面加一个8,就相当于79的子串&79的子串每一项都“加上”一个8,即{7,9,79,78,98,798,8}

然后就是第二个规律,79的字串中每一项%3所得出的结果中0,1,2的数量分别为{1,0,1},798的结果为{1,0,1,0,2,0,2},因为8%3=2,然后这个字串%3的结果可以看作{1,0,1,(1+8%3)%3,(0+8%3)%3,(1+8%3)%3,8%3}

然后可以推断出这个题是一个链式结构,随着字符的遍历,子串的长度一直递增,可以推断出转移方程dp[i][j] =dp[i][j]+ dp[i - 1][j] + dp[i - 1][(j + 3 - temp) % 3]

代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        int len = s.length();
        int mod = (int) (1e9 + 7);
        int[][] dp = new int[50][3];
        dp[0][s.charAt(0) % 3] = 1;
        for (int i = 1; i < len; i++) {
            int temp = s.charAt(i) % 3;
            dp[i][temp] = (dp[i][temp] + 1) % mod;
            for (int j = 0; j < 3; j++) {
                dp[i][j] += (dp[i - 1][j] + dp[i - 1][(j + 3 - temp) % 3]) % mod;
            }
        }
        System.out.println(dp[len - 1][0] % mod);
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值