zoukankan      html  css  js  c++  java
  • 【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<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #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<LL,int> 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&&u<k&&(dfs1(x+1,u+1,Fac[a[x]]+v),0);//选做阶乘
    }
    I void dfs2(CI x,CI u,CL v)//第二遍dfs,除统计答案过程大体同上
    {
    	if(x>n) 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<k&&(dfs2(x+1,u+1,Fac[a[x]]+v),0);
    }
    int main()
    {
    	RI i;for(scanf("%d%d%lld",&n,&k,&s),i=1;i<=n;++i) scanf("%d",a+i);//读入
    	for(Fac[0]=i=1;Fac[i-1]<=s;++i) Fac[i]=Fac[i-1]*i;m=i-1;//算阶乘
    	return dfs1(1,0,0),dfs2(n/2+1,0,0),printf("%lld",ans),0;//求解并输出
    }
    
  • 相关阅读:
    VSCode的终端修改
    vim总结
    分布式的CAP理论
    MongoDB常用命令总结
    nginx负载均衡总结
    【重要】nginx location配置和rewrite写法
    Linux四剑客find/grep/awk/sed
    IDEA插件开发总结
    支付宝在线支付接口开发流程
    Centos7 网卡Device does not seem to be present解决办法
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF525E.html
Copyright © 2011-2022 走看看