1. 程式人生 > >百度之星復賽&&hdu6148

百度之星復賽&&hdu6148

for 數字 namespace 技術分享 mar %d data while get

Problem Description

眾所周知,度度熊非常喜歡數字。

它最近發明了一種新的數字:Valley Number,像山谷一樣的數字。

技術分享

當一個數字,從左到右依次看過去數字沒有出現先遞增接著遞減的“山峰”現象,就被稱作 Valley Number。它可以遞增,也可以遞減,還可以先遞減再遞增。在遞增或遞減的過程中可以出現相等的情況。

比如,1,10,12,212,32122都是 Valley Number。

121,12331,21212則不是。

度度熊想知道不大於N的Valley Number數有多少。

註意,前導0是不合法的。

Input

第一行為T,表示輸入數據組數。

每組數據包含一個數N。

● 1≤T≤200

● 1≤length(N)≤100

Output

對每組數據輸出不大於N的Valley Number個數,結果對 1 000 000 007 取模。

Sample input 3 3 14 120 Sample Output 3 14 119
——————————————————————————————
一道很明顯的數位dp 然而寫掛了很多次QAQ
f【i】【j】【k】【l】
表示考慮到第i位 這一位為j 此時是否開始上升 以及前l-1為是否和n(原數)相等
轉移過程看代碼吧QAQ 比較難講 自己研究研究咯
技術分享
#include<cstdio>
#include
<cstring> #include<algorithm> #include<queue> using namespace std; const int mod=1e9+7,M=157; int read(){ int ans=0,f=1,c=getchar(); while(c<0||c>9){if(c==-) f=-1; c=getchar();} while(c>=0&&c<=9){ans=ans*10+(c-0); c=getchar();} return ans*f; }
int T,len,ans,h[M],f[M][15][2][2]; char s[M]; int calculate(int k){ memset(f,0,sizeof(f)); f[0][9][0][1]=1; for(int i=1;i<=k;i++){ int now=s[i]-0; for(int x=0;x<=9;x++){ for(int y=(i==1)?1:0;y<=9;y++){ for(int z=0;z<2;z++){ if(z&&y>now) continue; int nowf=(z&&y==now); if(x>=y){ if(x==y) f[i][y][1][nowf]=(f[i][y][1][nowf]+f[i-1][x][1][z])%mod; f[i][y][0][nowf]=(f[i][y][0][nowf]+f[i-1][x][0][z])%mod; } else{ f[i][y][1][nowf]=(f[i][y][1][nowf]+f[i-1][x][1][z])%mod; f[i][y][1][nowf]=(f[i][y][1][nowf]+f[i-1][x][0][z])%mod; } } } } } int sum=0; for(int x=0;x<=9;x++) for(int y=0;y<2;y++) for(int z=0;z<2;z++) sum=(sum+f[k][x][y][z])%mod; return sum; } void prepare(){ for(int i=1;i<=100;i++) s[i]=9; for(int i=1;i<=100;i++) h[i]=calculate(i); } int main() { prepare(); T=read(); while(T--){ ans=0; scanf("%s",s+1); len=strlen(s+1); for(int i=1;i<len;i++) ans=(ans+h[i])%mod; ans=(ans+calculate(len))%mod; printf("%d\n",ans); } return 0; }
View Code

百度之星復賽&&hdu6148