科大讯飞笔试

t3 dp

前置知识:
(a * b)% c = (a % c * b % c) % c
(a + b) % c = (a % c + b % c) % c

状态表示:
fij ==> 前i个字符构成的数取余p为j的方案数

状态转移:
f[i][(j * 10 % p + x % p) % p] += f[i-1][j]; 即:f[i][(j * 10 % p + x % p) % p]是由前i-1个字符构成的数取余为j的方案转移而来,即(a * 10 + b) % p,其中a为前i- 1个字符构成的数字,b为当前数字

package xunfei;

import java.io.*;
import java.util.Scanner;

public class Solution3 {
    static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
    static final int N = 110, M = 10010, MOD = (int) 1e9 + 7;
    static long[][] f = new long[N][M]; //fij前i和字符构成的数mod p 为j的方案数
    static int p;
    static String s;
    static char[] cs;

    static int nextInt() throws IOException {
        in.nextToken();
        return (int) in.nval;
    }

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        s = sc.nextLine();
        cs = s.toCharArray();
        int n = cs.length;
        p = nextInt();
        if (p == 0) out.println(0);
        else {
            if (cs[0] == '?') {
                for (int x = 0; x <= 9; x++) {
                    f[0][x % p]++;
                }
            } else {
                f[0][(cs[0] - '0') % p] = 1;
            }
            for (int i = 1; i < n; i++) {
                if (cs[i] == '?') {
                    for (int x = 0; x <= 9; x++) {
                        for (int j = 0; j < p; j++) {
                            //f[i][(int) ((f[i - 1][j] % p * x % p) % p)] += f[i - 1][j];
                            f[i][(j * 10 % p + x % p) % p] += f[i - 1][j];
                            f[i][(j * 10 % p + x % p) % p] %= MOD;
                        }
                    }
                } else {
                    int x = cs[i] - '0';
                    for (int j = 0; j < p; j++) {
                        //f[i][(int) ((f[i - 1][j] % p * x % p) % p)] += f[i - 1][j];
                        f[i][(j * 10 % p + x % p) % p] += f[i - 1][j];
                        f[i][(j * 10 % p + x % p) % p] %= MOD;
                    }
                }
            }
            out.println(f[n - 1][0]);
            out.close();
        }

    }
}




#科大讯飞##笔试#
全部评论
这个转移方程实在是太妙了,我一开始想的是三维dp,再加一个第i位赋值为x。但是怎么也想不出转移方程。说一下我对楼主算法的理解:对于f[i-1][j]其余数为j,代表的数字可以表示为k*p+j;当我们增加一位,并将该位的值赋值为x的时候,代表的数字为(k*p+j)*10+x;所以f[i-1][j]的下一位状态为f[i][(j*10+x)%p]。
3 回复 分享
发布于 2023-08-26 16:34 广东
太强了,第三题不会
2 回复 分享
发布于 2023-08-26 16:03 湖北
递归卡时间效率只过了10%😔😔
1 回复 分享
发布于 2023-08-26 16:02 北京
竟然第三题用dp,状态转移方程完全没思路,大佬牛
1 回复 分享
发布于 2023-08-26 16:03 美国
确实有这个说法,但是写的时候能想到也确实强
1 回复 分享
发布于 2023-08-26 16:08 广东
佬,看看realme手机秋招,全球Top5厂商,hc多多,岗位多多
1 回复 分享
发布于 2023-08-26 23:06 广东
点赞 回复 分享
发布于 2023-08-26 16:02 北京
第二题的题意没看懂,第二题那个我理解是只要用过相同字符集就+1,然后示例就G
点赞 回复 分享
发布于 2023-08-26 16:03 辽宁
大佬可以投递满帮保个底试试哈 https://www.nowcoder.com/feed/main/detail/a4df4a929a9148edb4a927e671a467e2?toCommentId=16770682
点赞 回复 分享
发布于 2023-08-26 16:07 江苏
我把前两道编程题写完了之后发现还有三分钟交卷
点赞 回复 分享
发布于 2023-08-26 16:09 四川
还得是大佬
点赞 回复 分享
发布于 2023-08-26 16:23 辽宁
为什么可以f[i][(j*10+x)%p]可以从f[i-1][j]转移过来呢?不是很理解,大佬可以解答一下吗
点赞 回复 分享
发布于 2023-08-27 15:41 浙江

相关推荐

喜欢走神的孤勇者练习时长两年半:池是池,发是发,我曾池,我现黑
点赞 评论 收藏
分享
牛客963010790号:为什么还要收藏
点赞 评论 收藏
分享
5 23 评论
分享
牛客网
牛客企业服务