【CF525E】Anya and Cubes(meet in middle)

点此看题面

大致题意:\(n\)个数中选任意个数,并使其中至多\(k\)个数\(x_i\)变为\(x_i!\),求使这些数和为\(S\)的方案数。

\(meet\ in\ middle\)

这应该是\(meet\ in\ middle\)一道比较板子的题目。

我们先对于一半的数,爆搜然后开\((k+1)\)\(map\)统计使用\(!\)个数小于等于\(i\),和为\(j\)的方案数。

然后对于另一半数,我们再爆搜一遍,到\(map\)中去找对应的情况使得使用\(!\)个数小于等于\(k\),和为\(j\)

并用一个变量\(ans\)统计答案。

由于一个数有选、不选、选做阶乘三种情况,所以时间复杂度为\(O(3^{\frac n2})\),而且加上剪枝之后还跑不满,稳过。

代码

#include
#define Tp template
#define Ts template
#define Reg register
#define RI Reg int
#define RL Reg LL
#define Con const
#define CI Con int&
#define CL Con LL&
#define I inline
#define W while
#define N 25
#define LL long long
using namespace std;
int n,m,k,a[N+5];LL s,ans,Fac[N+5];map p[N+5];
I void dfs1(CI x,CI u,CL v)//第一次dfs
{
    if(x>n/2) {for(RI i=u;i<=k;++i) ++p[i][v];return;}//用map存储该情况方案数
    dfs1(x+1,u,v),a[x]+v<=s&&(dfs1(x+1,u,a[x]+v),0),//不选/选
    a[x]<=m&&Fac[a[x]]+v<=s&&un) return (void)(ans+=p[k-u][s-v]);//统计答案
    dfs2(x+1,u,v),a[x]+v<=s&&(dfs2(x+1,u,a[x]+v),0),
    a[x]<=m&&Fac[a[x]]+v<=s&&u

转载于:https://www.cnblogs.com/chenxiaoran666/p/CF525E.html

你可能感兴趣的:(【CF525E】Anya and Cubes(meet in middle))