bzoj 1026 3029 数位dp

下午和cp,杰哥在一起做bzoj,交了自己的bzoj处女交,水了两道数位dp,前段时间学的数位dp模板好呀TUT

1026:http://www.lydsy.com/JudgeOnline/problem.php?id=1026

l到r之间相邻数绝对值差大于等于2数的个数

本来开三维记录当前位,前一位,有没有达到上限,发现不太妥,加了一维表示前面有没有放数

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 int dp[15][15],num[15];
 7 int dfs(int pos,int pre,int flag,int limit)
 8 {
 9   if (pos==0) return flag==0;
10   if (!limit&&!flag&&dp[pos][pre]!=-1)
11     return dp[pos][pre];
12   int i,ans=0,tmp=limit?num[pos]:9;
13   for (i=0;i<=tmp;i++)
14     if (flag||i-pre>=2||i-pre<=-2)
15       ans+=dfs(pos-1,i,flag&&i==0,limit&&i==tmp);
16   if (!limit&&!flag)
17     dp[pos][pre]=ans;
18   return ans;
19 }
20 int solve(int x)
21 {
22   int cnt=0;
23   while (x!=0)
24   {
25     num[++cnt]=x%10;
26     x/=10;
27   }
28   return dfs(cnt,-1,1,1);
29 }
30 int main()
31 {
32   int x,a,b;
33   memset(dp,-1,sizeof(dp));
34   while (~scanf("%d%d",&a,&b))
35   {
36     if (a>b) {x=a; a=b; b=x; }
37     printf("%d\n",solve(b)-solve(a-1));
38   }
39   return 0;
40 }
View Code

3209:http://www.lydsy.com/JudgeOnline/problem.php?id=3209

1到n之间每个数二进制包含1个数乘积。

枚举包含1个数然后分别dfs,最后加个快速幂计算就好啦

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define MOD 10000007
 4 #define LL long long
 5 LL dp[55][55][55],num[55];
 6 LL dfs(int pos,int sum,int need,int limit)
 7 {
 8   if (sum>need) return 0;
 9   if (pos==0) return sum==need;
10   if (!limit&&dp[pos][sum][need]!=-1)
11     return dp[pos][sum][need];
12   int i,tmp=limit?num[pos]:1;
13   LL ans=0;
14   for (i=0;i<=tmp;i++)
15     ans+=dfs(pos-1,sum+i,need,limit&&i==tmp);
16   if (!limit)
17     dp[pos][sum][need]=ans;
18   return ans;
19 }
20 LL quick(LL a,LL b,LL m)
21 {
22   LL ans=1;
23   a=a%m;
24   while (b!=0)
25   {
26     if (b%2) ans=(ans%m)*(a%m)%m;
27     b/=2;
28     a=(a%m)*(a%m)%m;
29   }
30   return ans;
31 }
32 int main()
33 {
34   LL n,x,ans,tmp;
35   int cnt,i;
36   memset(dp,-1,sizeof(dp));
37   while (~scanf("%lld",&n))
38   {
39     cnt=0; x=n;
40     while (x!=0)
41     {
42       num[++cnt]=x%2;
43       x/=2;
44     }
45     ans=1;
46     for (i=1;i<=cnt;i++)
47     {
48       tmp=dfs(cnt,0,i,1);
49       if (tmp!=0) ans=ans*(quick((LL)i,tmp,MOD)%MOD)%MOD;
50     }
51     printf("%lld\n",ans);
52   }
53 }
View Code

 

posted on 2014-12-27 17:18  xiao_xin  阅读(126)  评论(0)    收藏  举报

导航