HDU 6148 Valley Numer (數位DP)
阿新 • • 發佈:2018-11-28
題目大意:當一個數字,從左到右依次看過去數字沒有出現先遞增接著遞減的“山峰”現象,就被稱作 Valley Number。它可以遞增,也可以遞減,還可以先遞減再
遞增。在遞增或遞減的過程中可以出現相等的情況。
比如,1,10,12,212,32122都是 Valley Number。
121,12331,21212則不是。
LJJ想知道不大於N的Valley Number數有多少。
注意,前導0是不合法的。
這道題前導0的情況非常好處理,遍歷每一位都新生成一個1~9就行了
定義$f[i][j][0/1][0/1]$表示第$i$位,最後一位是$j$,是否達到上界,前一段是否遞增
然後分情況討論就行了
由於直接討論十分複雜,可以按每一維進行討論
先討論是否遞增,然後討論是否達到上限
然後把討論的$DP$按乘法原理"合併"一下就行了
這算是一個技巧吧
我竟然1A了
1 #include <cmath> 2 #include <queue> 3 #include <vector> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #define N1 121 8 #define N2 4201 9#define M1 120 10 #define ll long long 11 #define dd double 12 #define uint unsigned int 13 #define idx(X) (X-'0') 14 #define mod 1000000007 15 using namespace std; 16 17 int gint() 18 { 19 int ret=0,fh=1;char c=getchar(); 20 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 21 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 22 return ret*fh; 23 } 24 int T,n; 25 char str[N1]; 26 int a[N1]; 27 uint f[N1][10][2][2]; 28 29 int main() 30 { 31 //freopen("t1.in","r",stdin); 32 scanf("%d",&T); 33 while(T--) 34 { 35 36 scanf("%s",str+1); 37 n=strlen(str+1); 38 for(int i=1;i<=n;i++) 39 a[i]=idx(str[i]); 40 memset(f,0,sizeof(f)); 41 for(int i=1;i<a[1];i++) 42 f[1][i][0][0]=1; 43 f[1][a[1]][1][0]=1; 44 for(int i=1;i<n;i++) 45 { 46 for(int j=0;j<=9;j++) 47 { //nolimit 48 for(int k=0;k<j;k++) //down 49 { 50 (f[i+1][k][0][0]+=f[i][j][0][0])%=mod; 51 if(k<a[i+1]) 52 (f[i+1][k][0][0]+=f[i][j][1][0])%=mod; 53 else if(k==a[i+1]) 54 (f[i+1][k][1][0]+=f[i][j][1][0])%=mod; 55 } 56 //plain 57 (f[i+1][j][0][0]+=f[i][j][0][0])%=mod; 58 (f[i+1][j][0][1]+=f[i][j][0][1])%=mod; 59 if(j<a[i+1]){ 60 (f[i+1][j][0][0]+=f[i][j][1][0])%=mod; 61 (f[i+1][j][0][1]+=f[i][j][1][1])%=mod; 62 }else if(j==a[i+1]){ 63 (f[i+1][j][1][0]+=f[i][j][1][0])%=mod; 64 (f[i+1][j][1][1]+=f[i][j][1][1])%=mod; 65 } 66 //up 67 for(int k=j+1;k<=9;k++) 68 { 69 (f[i+1][k][0][1]+=f[i][j][0][0])%=mod; 70 (f[i+1][k][0][1]+=f[i][j][0][1])%=mod; 71 if(k<a[i+1]){ 72 (f[i+1][k][0][1]+=f[i][j][1][0])%=mod; 73 (f[i+1][k][0][1]+=f[i][j][1][1])%=mod; 74 }else if(k==a[i+1]){ 75 (f[i+1][k][1][1]+=f[i][j][1][0])%=mod; 76 (f[i+1][k][1][1]+=f[i][j][1][1])%=mod; 77 } 78 } 79 } 80 for(int j=1;j<=9;j++) 81 (f[i+1][j][0][0]+=1)%=mod; 82 } 83 uint ans=0; 84 for(int k=0;k<=9;k++) 85 { 86 (ans+=f[n][k][0][0]+f[n][k][0][1])%=mod; 87 (ans+=f[n][k][1][0]+f[n][k][1][1])%=mod; 88 } 89 printf("%u\n",ans); 90 91 } 92 return 0; 93 }