Atcoder Regular 058 E
阿新 • • 發佈:2019-02-16
題目大意:問有多少長度為N的數列{aN},滿足每個數字權值在[1,10]中,並且不存在1<=x
#include<iostream>
#include<cstring>
#include<cstdio>
#define lint long long
#define LOG 17
#define maxK 10
#define V 1<<LOG
#define N 42
#define mod 1000000007
using namespace std;
inline int updv(int x,int p) { return x|(1<<(p-1 )); }
int dp[N][V],can[V];
int fast_pow(int x,int k)
{
int ans=1;
while(k)
{
if(k&1) ans=(lint)ans*x%mod;
x=(lint)x*x%mod,k>>=1;
}
return ans;
}
int show(int x)
{
for(int i=1;i<=LOG;i++)
printf("%d",(x&(1<<(i-1)))>>(i-1));
cout<<endl;
return 0;
}
int main()
{
int n,x,y,z;scanf("%d%d%d%d",&n,&x,&y,&z);
int all=(1<<LOG)-1,v=0,ans=0;dp[0][0]=1;
v=updv(v,x+y+z),v=updv(v,y+z),v=updv(v,z);
for(int i=0;i<=all;i++) can[i]=((i&v)!=v);
for(int i=0,x;i<n;i++)
for(int j=0;j<=all;j++)
if (can[j]&&(x=dp[i][j]))
for(int k=1;k<=maxK;k++)
(dp[i+1][all&updv(j<<k,k)]+=x)%=mod;
for(int i=1;i<=all;i++)
if(can[i]) (ans+=dp[n][i])%=mod;
printf("%d\n",(fast_pow(10,n)-ans+mod)%mod);
return 0;
}