1. 程式人生 > >Atcoder Regular 058 E

Atcoder Regular 058 E

題目大意:問有多少長度為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; }