HDU-3652(数位dp)

Posted wanshe-li

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-3652(数位dp)相关的知识,希望对你有一定的参考价值。

#pragma warning (disable : 4996)

#include<iostream>
#include<algorithm>
//#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
using namespace std;
#define INF 0x3f3f3f3f
#define inf 0x7FFFFFFF
#define MOD 1000000007
#define pii pair<ll,ll>
#define eps 1e-8
#define equals(a,b) (fabs(a-b)<eps)
#define bug puts("bug******************bug")
#define re  register
#define fi first
#define se second
#define mem(a, b) memset(a, b, sizeof a)
#define speed std::ios::sync_with_stdio(false)
#define pb push_back
const double Inf = 10000.0;
const double PI = acos(-1.0);
typedef long long ll;
typedef unsigned long long ull;
inline int rd() {
	int X = 0, w = 0; char ch = 0; while (!isdigit(ch)) { w |= ch == ‘-‘; ch = getchar(); }
	while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar(); return w ? -X : X;
}

int n, pos;
int num[15];
//int dp[15][15][15][2];
int dp[15][3][15];//dp[pos][str][mod]
//str = 0表示前面无13且前一位不为1, str = 1表示前一位是1, str = 2表示前面有13
void init(int n) {
	pos = 0;
	while (n) {
		num[pos++] = n % 10;
		n /= 10;
	}
	mem(dp, -1);
}

int get(int str, int i) {
	if (str == 0) {
		if (i == 1)	return 1;
		else	return 0;
	}
	if (str == 1) {
		if (i == 1)	return 1;
		if (i == 3)	return 2;
		return 0;
	}
	return str;
}

int dfs(int pos, int str, int mod, int limit) {
	if (pos == -1)	return !mod && (str == 2);//余数为0且有13
	if (!limit && ~dp[pos][str][mod])	return dp[pos][str][mod];
	int up = limit ? num[pos] : 9, ans = 0;
	for (int i = 0; i <= up; ++i) {
		printf("pos = %d str = %d mod = %d i = %d limit = %d ans = %d
", pos, str, mod, i, limit, ans);
		ans += dfs(pos - 1, get(str, i), (mod * 10 + i) % 13, limit && i == up);
	}
	return limit ? ans : dp[pos][str][mod] = ans;
}

/*int dfs(int pos, int pre, int mod, int is, int bk) {
	if (pos == -1) {
		if (is && !mod)	printf("pos = %d pre = %d
", pos, pre);
		return is && !mod;
	}
	if (!bk && dp[pos][pre][mod][is] != -1) return dp[pos][pre][mod][is];
	int end = bk ? num[pos] : 9;
	int sum = 0;
	for (int i = 0; i <= end; ++i) {
		int mod_ = (mod * 10 + i) % 13;
		if (pre == 1 && i == 3)	sum += dfs(pos - 1, i, mod_, 1, bk && i == end);
		else	sum += dfs(pos - 1, i, mod_, is, bk && i == end);
	}
	return bk ? sum : dp[pos][pre][mod][is] = sum;
}*/


int main() {
	while (~scanf("%d", &n)) {
		init(n);
		printf("%d
", dfs(pos - 1, 0, 0, 1));
	}
	return 0;
}



以上是关于HDU-3652(数位dp)的主要内容,如果未能解决你的问题,请参考以下文章

HDU-3652(数位dp)

hdu3652 数位dp

hdu-3652 B-number 数位DP

HDU 3652 - B-number - [数位DP]

HDU3652--容斥+数位dp

hdu3652 数位dp记忆化搜索