• 线性dp,毫哥和巨佬的故事


    Contest (nefu.edu.cn)

    Problem:E
    Time Limit:10000ms
    Memory Limit:262144K

    Description

    众所周知,毫哥和巨佬是好朋友,他们各有所好,毫哥喜欢数字,巨佬喜欢取余,有一天他们决定来玩一个游戏来决定谁的能力更高。
    毫哥说决定我的能力的数字中的各个位的值不能包含0,并且数字的各个位的值的和得等于x;例如:x=5时,满足毫哥的能力值可以为:113, 23, 5但是对于50虽然和是5,但是含有0就不是毫哥的能力值。
    巨佬说决定我的能力的数字必须得整除y;例如:y=10时,0,100,200等都是巨佬的能力值。
    于是他们找来了好朋友康康,希望康康帮助他们统计出同时满足他们2个人条件的能力值有多少个?由于答案很大,请你对1000000007取模。
    0 
    

    Input

    输入一行一个x,一个y。

    Output

    输同时满足两个条件的能力值的个数。

    Sample Input

    3 6

    Sample Output

    1

    解析:

    状态更新方式:用当前状态更新依赖他的状态


     这道题不容易想到用dp来做
     DP的核心思想是用集合来表示一类方案,然后从集合的维度来考虑状态之间的递推关系。
     受上述性质启发,状态表示为:
     f[i][k]表示为当前只需要加上i即可等于x,且模y等于k;
     我们可以发现这是一个不重不漏的集合划分方式
     则状态的转移方式为
     f[i-j][(k*10+j)%y]+=f[i][k];
     i: x到0
     j: 1到9
     k:0到y
     初始化为f[x][0]=1;
     最终答案为f[0][0];

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. using namespace std;
    15. typedef long long LL;
    16. const LL N = 5e4 + 5, M = 500 + 5, mod = 1e9 + 7;
    17. LL x, y;
    18. LL f[N][M];
    19. int main() {
    20. scanf("%d%d", &x, &y);
    21. f[x][0] = 1;
    22. for (int i = x; i >= 0; i--) {
    23. for (int j = 1; j <= min(i, 9); j++) {
    24. for (int k = 0; k <= y - 1; k++) {
    25. f[i - j][(k * 10 + j) % y] += f[i][k];
    26. f[i - j][(k * 10 + j) % y] %= mod;
    27. }
    28. }
    29. }
    30. cout << f[0][0] << endl;
    31. return 0;
    32. }

  • 相关阅读:
    LeetCode01
    Vue模板语法
    SpringBoot数据响应、分层解耦、三层架构
    Linux目录
    使用Java语言深度探索数据结构中的单向链表:完美结合详解与示例代码
    物联网环境中基于深度学习的差分隐私预算优化方法
    深入理解数组
    【数据结构】二叉树的层序遍历、前序遍历,中序遍历、后续遍历
    错误码:spark_error_00000004
    史上最简洁Kotlin版EventBus的使用教程
  • 原文地址:https://blog.csdn.net/Landing_on_Mars/article/details/133238059