[BZOJ 1026] [SCOI 2009] Windy数 【数位DP】
生活随笔
收集整理的這篇文章主要介紹了
[BZOJ 1026] [SCOI 2009] Windy数 【数位DP】
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目鏈接:BZOJ - 1026
?
題目分析
這道題是一道數(shù)位DP的基礎(chǔ)題,對(duì)于完全不會(huì)數(shù)位DP的我來說也是難題..
對(duì)于詢問 [a,b] 的區(qū)間的答案,我們對(duì)詢問進(jìn)行差分,求 [0,b] - [0,a-1] 的答案。這樣就化繁為簡了。
具體過程見代碼中的注釋。
?
代碼
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm>using namespace std;const int MaxBit = 13;int A, B; int f[MaxBit][11], Bit[MaxBit];inline int Abs(int a) {return a >= 0 ? a : -a; }//計(jì)算小于x的數(shù)的答案 int Get(int x) {if (x == 0) return 0;int ret = 0, l = 0;while (x) {Bit[++l] = x % 10;x /= 10;}//統(tǒng)計(jì)位數(shù)不足l位的答案 for (int i = 1; i <= l - 1; ++i) {for (int j = 1; j <= 9; ++j) {ret += f[i][j];}}//最高位可以在[1, Bit[l]-1]之間變化 for (int i = 1; i <= Bit[l] - 1; ++i) ret += f[l][i];//固定后面的(l-i)位,然后第i位可以在[0, Bit[i]-1]之間變化 for (int i = l - 1; i >= 1; --i) {for (int j = 0; j <= Bit[i] - 1; ++j) {if (Abs(j - Bit[i + 1]) >= 2) ret += f[i][j];}//無法固定第i位 if (Abs(Bit[i + 1] - Bit[i]) < 2) break;}return ret; }int main() {//f[i][j]表示第i位是j的答案數(shù) for (int i = 0; i <= 9; ++i) f[1][i] = 1;for (int i = 1; i <= 10; ++i) {for (int j = 0; j <= 9; ++j) {for (int k = 0; k <= 9; ++k) {if (Abs(k - j) >= 2) f[i][j] += f[i - 1][k];}}}scanf("%d%d", &A, &B);//對(duì)詢問進(jìn)行差分,化繁為簡 printf("%d\n", Get(B + 1) - Get(A));return 0; }
轉(zhuǎn)載于:https://www.cnblogs.com/JoeFan/p/4231594.html
總結(jié)
以上是生活随笔為你收集整理的[BZOJ 1026] [SCOI 2009] Windy数 【数位DP】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java okhttp包的类特点
- 下一篇: 【吉比特】G-bits2017技术类岗位