FZU 1896 神奇的魔法数 dp

网上都说是数位dp 但是虽然在队伍里负责动态规划 但是数位dp还不会……

百度了一下 发现和最大子序列思路差不多……

最大子序列的dp[i][j]是表示两个序列前i项和前j项的最大子序列……

dp[i][j]表示前i位 尾数是j的魔法数的个数……

也不是特别不好理解……

但是还要好好理解一下……

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 int dp[15][15];
 8 int a,b,m;
 9 
10 long long func(int x){
11     int number[15],len=0;
12     long long sum=0;
13     number[0]=0;
14     while(x){
15         number[++len]=x%10;
16         x/=10;
17     }
18     for(int i=1;i<len;i++)
19         for(int j=1;j<10;j++)
20             sum+=dp[i][j];
21     for(int i=1;i<number[len];i++)
22         sum+=dp[len][i];
23     for(int i=len-1;i>0;i--){
24         for(int j=0;j<number[i];j++){
25             if(abs(j-number[i+1])>=m) sum+=dp[i][j];
26         }
27         if(abs(number[i]-number[i+1])<m) break;
28     }
29     return sum;
30 }
31 
32 int main(){
33     int T;
34     scanf("%d",&T);
35     while(T--){
36         scanf("%d%d%d",&a,&b,&m);
37         for(int i=0;i<10;i++)
38             dp[1][i]=1;
39         for(int i=2;i<12;i++)
40             for(int j=0;j<10;j++)
41                 for(int k=0;k<10;k++)
42                     if(abs(j-k)>=m)
43                         dp[i][j]+=dp[i-1][k];
44         printf("%lld\n",func(b+1)-func(a));
45         memset(dp,0,sizeof(dp));
46     }
47     return 0;
48 }

 

posted @ 2016-04-21 19:42  良将ℓ  阅读(164)  评论(0编辑  收藏  举报