Codeforces Round #297 (Div. 二) E Anya and Cubes
Codeforces Round #297 (Div. 2) E Anya and Cubes
参考链接: http://www.cnblogs.com/qscqesze/p/4371851.html
给你n个数,k个魔法棒,s为所求的数,然后让你找有多少种方法,能够使的这n个数之和为s,其中一个魔法棒可以使的一个数变成他的阶乘
折半搜索
对于每一个数,都有三种策略,拿,不拿,使用魔法棒
那么我们就直接折半搜索然后扔进一个map里面,然后就查询
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<vector> #include<set> #include<map> #define L(x) (x<<1) #define R(x) (x<<1|1) #define MID(x,y) ((x+y)>>1) #define eps 1e-8 typedef long long ll; #define fre(i,a,b) for(i = a; i <b; i++) #define free(i,b,a) for(i = b; i >= a;i--) #define mem(t, v) memset ((t) , v, sizeof(t)) #define ssf(n) scanf("%s", n) #define sf(n) scanf("%d", &n) #define sff(a,b) scanf("%d %d", &a, &b) #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c) #define pf printf #define bug pf("Hi\n") using namespace std; #define INF 0x3f3f3f3f #define N 30 ll a[N],n,k,s; ll mid; struct stud{ ll step,result; }f[1111111]; ll p[20]; ll cnt; map<ll,ll>mp[30]; void inint() { int i,j; p[0]=1; p[1]=1; fre(i,2,20) p[i]=p[i-1]*i; } void dfs(ll pos,ll num,ll va) { if(num>k||va>s) return ; if(pos==mid+1) { f[cnt].step=num; f[cnt++].result=va; return ; } dfs(pos+1,num,va); dfs(pos+1,num,va+a[pos]); if(a[pos]<20) dfs(pos+1,num+1,va+p[a[pos]]); } void DFS(ll pos,ll num,ll va) { if(num>k||va>s) return ; if(pos==n+1) { mp[num][va]++; return ; } DFS(pos+1,num,va); DFS(pos+1,num,va+a[pos]); if(a[pos]<20) DFS(pos+1,num+1,va+p[a[pos]]); } int main() { ll i,j; inint(); while(~scanf("%I64d%I64d%I64d",&n,&k,&s)) { fre(i,1,n+1) scanf("%I64d",&a[i]); fre(i,0,30) mp[i].clear(); mid=MID(0,n); cnt=0; dfs(1,0,0); DFS(mid+1,0,0); ll ans=0; fre(j,0,cnt) fre(i,0,k-f[j].step+1) ans+=mp[i][s-f[j].result]; pf("%I64d\n",ans); } return 0; }