hdu3652 数位dp经典
来源:互联网 发布:其恕乎是什么意思 编辑:程序博客网 时间:2024/06/14 05:26
*Get:非常经典的数位dp,用模板化limit dfs的方式写比较直接,状态定义见代码注解.这里发现这样模板化之后,
*只需要每次都来倒着拆分这个数为数字,然后倒着扩展(还原回去是从左到右扩展),就可以解决连续数字串,固定
*余数的问题.而且加入的limit让最后的扩展变得非常模板化,十分简洁.试想这个写成递推,会非常繁杂的解决limit问题.
/**********************jibancanyang************************** *Author :jibancanyang *Created Time : 二 4/19 00:05:58 2016 *File Name : hdu3652.cpp *Problem:数位dp经典***********************1599664856@qq.com**********************/#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <stack>using namespace std;typedef pair<int, int> pii;typedef long long ll;typedef unsigned long long ull;vector<int> vi;#define pr(x) cout << #x << ": " << x << " " #define pl(x) cout << #x << ": " << x << endl;#define xx first#define yy second#define sa(n) scanf("%d", &(n))#define rep(i, a, n) for (int i = a; i < n; i++)#define vep(c) for(decltype((c).begin() ) it = (c).begin(); it != (c).end(); it++) const int mod = 13, INF = 0x3fffffff, maxn = 1e5 + 12;int bit[11], n, dp[11][13][2][2], t, x;//扩展到第len位, 余数为res, 到目前为止是否有13出现, 上一位是否为1, 本位是否有限制int dfs(int len, int res, bool have, bool cur, bool limit) { //pr(len), pr(res), pr(have), pr(cur), pl(limit); if (len == -1) return have && res == 0; if (!limit && dp[len][res][have][cur] != -1) return dp[len][res][have][cur]; int m = limit ? bit[len] : 9; int ret = 0; for (int i = 0; i <= m; i++) { ret += dfs(len - 1, (res * 10 % mod + i) % mod, have || (cur && i == 3), i == 1, limit && i == m); } if (!limit) dp[len][res][have][cur] = ret; return ret;}int solve(int n) { t = 0, x = n; while (x) { bit[t++] = x % 10; x /= 10; } return dfs(t - 1, 0, false, false, true);}int main(void){#ifdef LOCAL //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout);#endif cin.sync_with_stdio(false); memset(dp, -1, sizeof(dp)); while (cin >> n) { cout << solve(n) << endl; } return 0;}
笔者的另一种思路:
这里的res记录不符合常规dp思想,是因为取余的性质,记录左边已得,还是右边需求都一样。
/**********************jibancanyang************************** *Author* :jibancanyang *Created Time* : 四 6/16 21:00:50 2016**Problem**:**Analyse**:**Get**:**Code**:***********************1599664856@qq.com**********************/#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <stack>using namespace std;typedef pair<int, int> pii;typedef long long ll;typedef unsigned long long ull;typedef vector<int> vi;#define pr(x) cout << #x << ": " << x << " " #define pl(x) cout << #x << ": " << x << endl;#define pri(a) printf("%d\n",(a))#define xx first#define yy second#define sa(n) scanf("%d", &(n))#define sal(n) scanf("%lld", &(n))#define sai(n) scanf("%I64d", &(n))#define vep(c) for(decltype((c).begin() ) it = (c).begin(); it != (c).end(); it++) const int mod = int(1e9) + 7, INF = 0x3f3f3f3f;const int maxn = 1e5 + 13;int bits[11];int dp[11][10][2][13];//have的意义是是否还需要13的出现。int dfs(int len, int high, bool have, bool limit, int res) { if (len == 0) { return !have && (res == 0); } if (!limit && dp[len][high][have][res] != -1) return dp[len][high][have][res]; int m = limit ? bits[len] : 9; int ret = 0; for (int i = 0; i <= m; i++) { if ( (high == 1 && i == 3) || !have ) ret += dfs(len - 1, i, false, limit && i == m, (res * 10 + i) % 13 ); else ret += dfs(len - 1, i, true, limit && i == m, (res * 10 + i) % 13); } if (!limit) dp[len][high][have][res] = ret; return ret;}int solve(int n) { int t = 1; while (n) { bits[t++] = n % 10; n /= 10; } bits[t] = 9; return dfs(t - 1, 9, true, true, 0);}int main(void){#ifdef LOCAL freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout);#endif int r; memset(dp, -1, sizeof(dp)); while (~sa(r)) { pri(solve(r)); } return 0;}
0 0
- hdu3652 数位dp经典
- hdu3652 数位dp
- hdu3652(数位DP)
- hdu3652(数位DP)
- hdu3652(数位dp)
- hdu3652 数位DP
- HDU3652数位DP
- hdu3652(数位dp)
- hdu3652(数位dp)
- HDU3652(数位DP)
- hdu3652(数位dp
- 【hdu3652】【数位DP】
- 数位dp-HDU3652
- 【数位DP】 hdu3652 B-number
- 【hdu3652】【数位DP】B-number
- 【数位DP】B-number HDU3652
- HDU3652:B-number(数位DP)
- hdu3652 B-number (数位DP)
- 安装Hadoop需要配置的几个文件
- 2.《Unity中C#脚本语法-常用变量类型》
- 一步一步配置ssh免密码登陆配置ssh免密码登陆
- 轻松入门Github
- 1010 of search
- hdu3652 数位dp经典
- SpringMVC+Spring+Mybatis整合程序之整合
- 一个图片轮播插件---Nivo Slider
- 判断List、Map、Set是否为空及效率比较
- NY115 城市平乱
- 单例设计模式
- 时间可视化分析平台
- 什么时候用GET?什么时候用POST?
- 【服务器编程】服务器编程实现逻辑和超级服务