线性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<x<=50000 0<y<=500

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];

cpp 复制代码
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
using namespace std;
typedef long long LL;
const LL N = 5e4 + 5, M = 500 + 5, mod = 1e9 + 7;
LL x, y;
LL f[N][M];

int main() {
	scanf("%d%d", &x, &y);
	f[x][0] = 1;
	for (int i = x; i >= 0; i--) {
		for (int j = 1; j <= min(i, 9); j++) {
			for (int k = 0; k <= y - 1; k++) {
				f[i - j][(k * 10 + j) % y] += f[i][k];
				f[i - j][(k * 10 + j) % y] %= mod;
			}
		}
	}
	cout << f[0][0] << endl;
	return 0;
}
相关推荐
大数据张老师3 小时前
数据结构——邻接矩阵
数据结构·算法
低音钢琴4 小时前
【人工智能系列:机器学习学习和进阶01】机器学习初学者指南:理解核心算法与应用
人工智能·算法·机器学习
傻童:CPU6 小时前
C语言需要掌握的基础知识点之前缀和
java·c语言·算法
又见野草6 小时前
软件设计师知识点总结:数据结构与算法(超级详细)
数据结构·算法·排序算法
GalaxyPokemon6 小时前
有一个服务器,用于提供HTTP服务,但是需要限制每个用户在任意的100秒内只能请求60次,怎么实现这个功能
算法
fl1768317 小时前
基于opencv+Mediapipe+CNN实现用手势识别控制对鼠标操控python源码+项目说明+设计文档
算法
K 旺仔小馒头7 小时前
优选算法:01 双指针巧解移动零问题
c++·算法·刷题
sali-tec8 小时前
C# 基于halcon的视觉工作流-章49-网面破损
开发语言·图像处理·算法·计算机视觉·c#
ysa0510308 小时前
Fenwick 树进行快速统计
算法
im_AMBER8 小时前
Leetcode 33
算法·leetcode·职场和发展