https://ac.nowcoder.com/acm/contest/5026/C
思路一:dpdpdp,首先通过并查集处理出所有的连通块(限制条件),然后用dpi,x,y,z,wdp_{i,x,y,z,w}dpi,x,y,z,w​表示处理第iii个连通块时,选了xxx个AAA、yyy个BBB、zzz个CCC、www个DDD时的方案数,枚举转移即可,详见代码。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;int n,m;
int a[4],f[15],vis[15],idx[15],cnt[15];
ll dp[13][13][13][13][13];int father(int x)
{return f[x]==x?x:f[x]=father(f[x]);
}int main()
{for(int i=1;i<=12;i++)f[i]=i;for(int i=0;i<4;i++)scanf("%d",&a[i]);scanf("%d",&m);int x,y,fx,fy;while(m--){scanf("%d%d",&x,&y);fx=father(x),fy=father(y);if(fx!=fy)f[fx]=fy;}int id=0,idx;for(int i=1;i<=12;i++){fx=father(i);if(!vis[fx])vis[fx]=++id;idx=vis[fx];++cnt[idx];}dp[0][0][0][0][0]=1;for(int i=1;i<=id;i++){for(int x=0;x<=a[0];x++){for(int y=0;y<=a[1];y++){for(int z=0;z<=a[2];z++){for(int w=0;w<=a[3];w++){if(dp[i-1][x][y][z][w]){if(x+cnt[i]<=a[0])dp[i][x+cnt[i]][y][z][w]+=dp[i-1][x][y][z][w];if(y+cnt[i]<=a[1])dp[i][x][y+cnt[i]][z][w]+=dp[i-1][x][y][z][w];if(z+cnt[i]<=a[2])dp[i][x][y][z+cnt[i]][w]+=dp[i-1][x][y][z][w];if(w+cnt[i]<=a[3])dp[i][x][y][z][w+cnt[i]]+=dp[i-1][x][y][z][w];}}}}}}printf("%lld\n",dp[id][a[0]][a[1]][a[2]][a[3]]);return 0;
}

思路二:爆搜+组合,假设在处理完所有的限制条件之后,A、B、C、DA、B、C、DA、B、C、D的数量还剩下a、b、c、da、b、c、da、b、c、d个,不妨设sum=a+b+c+dsum=a+b+c+dsum=a+b+c+d,那么此时的方案数量就等于C(sum,a)∗C(sum−a,b)∗C(sum−a−b,c)∗C(sum−a−b−c,d)C(sum,a)*C(sum-a,b)*C(sum-a-b,c)*C(sum-a-b-c,d)C(sum,a)∗C(sum−a,b)∗C(sum−a−b,c)∗C(sum−a−b−c,d)。那么预处理出所有的连通块后,删去仅有111个元素的连通块(相当于该位置没有限制条件)后,爆搜处理即可。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;int n,m,num;
ll ans;
int a[4],f[15],vis[15],idx[15],cnt[15];
ll C[15][15];int father(int x)
{return f[x]==x?x:f[x]=father(f[x]);
}void dfs(int j,int len)
{if(j>len){int s0=a[0],s1=s0+a[1],s2=s1+a[2];ans+=C[num][a[0]]*C[num-s0][a[1]]*C[num-s1][a[2]]*C[num-s2][a[3]];return ;}for(int i=0;i<4;i++){if(a[i]>=cnt[j]){a[i]-=cnt[j];dfs(j+1,len);a[i]+=cnt[j];}}
}int main()
{for(int i=0;i<=12;i++)C[i][0]=1;C[1][1]=1;for(int i=2;i<=12;i++)for(int j=1;j<=i;j++)C[i][j]=C[i-1][j-1]+C[i-1][j];for(int i=1;i<=12;i++)f[i]=i;for(int i=0;i<4;i++)scanf("%d",&a[i]);scanf("%d",&m);int x,y,fx,fy;while(m--){scanf("%d%d",&x,&y);fx=father(x),fy=father(y);if(fx!=fy)f[fx]=fy;}int id=0,idx;num=12;for(int i=1;i<=12;i++){fx=father(i);if(!vis[fx])vis[fx]=++id;idx=vis[fx];++cnt[idx];--num;}sort(cnt+1,cnt+1+id,greater<int>());while(cnt[id]==1)--id,++num;dfs(1,id);printf("%lld\n",ans);return 0;
}

牛客练习赛61 C 四个选项 dp\搜索+组合数学相关推荐

  1. 牛客练习赛61 C 四个选项(并查集、DP、排列组合)难度⭐⭐⭐

    链接:https://ac.nowcoder.com/acm/contest/5026/C 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64 ...

  2. 牛客练习赛 61(待补F-点分治?)

    A. 打怪 先求出每次打死一只怪需要掉多少血,然后就直接算出能够打死多少只. #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) ...

  3. 牛客练习赛61 - B - 吃水果

    题目描述 最近米咔买了n个苹果和m个香蕉,他每天可以选择吃掉一个苹果和一个香蕉(必须都吃一个,即如果其中一种水果的数量为0,则他不能进行这个操作),或者使用魔法将某一种水果的数量翻倍. 现在米咔想吃西 ...

  4. 牛客练习赛61 B 吃水果 题解

    链接:https://ac.nowcoder.com/acm/contest/5026/B 来源:牛客网 题目描述 最近米咔买了n个苹果和m个香蕉,他每天可以选择吃掉一个苹果和一个香蕉(必须都吃一个, ...

  5. subsequence 1(牛客多校第五场记忆化搜索+组合数学)

    链接:https://ac.nowcoder.com/acm/contest/885/G 来源:牛客网 题目描述 You are given two strings s and t composed ...

  6. 牛客练习赛61 D 最短路变短了(最短路,反向最短路)难度⭐⭐⭐★

    最短路变短了 链接 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format:%lld 题目描述 给定一个有向带权图,其中 ...

  7. 牛客练习赛61 E 相似的子串(二分+哈希)难度⭐⭐⭐

    相似的子串 题目链接 时间限制:C/C++ 4秒,其他语言8秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format:%lld 题目描述 给定一个字符串,要求取 ...

  8. 牛客练习赛61 B 吃水果

    题目描述 最近米咔买了n个苹果和m个香蕉,他每天可以选择吃掉一个苹果和一个香蕉(必须都吃一个,即如果其中一种水果的数量为0,则他不能进行这个操作),或者使用魔法将某一种水果的数量翻倍. 现在米咔想吃西 ...

  9. 牛客练习赛79E-小G的数学难题【dp,单调队列】

    正题 题目链接:https://ac.nowcoder.com/acm/contest/11169/E 题目大意 给出nnn个三元组(ai,bi,ci)(a_i,b_i,c_i)(ai​,bi​,ci ...

最新文章

  1. socks5   代理
  2. R 语言中 X11 相关的一些问题
  3. 图像特征检测(Image Feature Detection)
  4. 挑战权威还是偏离主流?颠覆性研究或将证明神经信号是机械波
  5. Ubuntu 下编译ffmpeg和x264解编码器(翻译的一篇文章:)
  6. 深度学习(十一)RNN入门学习
  7. 产品经理在工作中如何进行沟通
  8. websocket连接mysql_websocket 使用 spring 的service层 ,进而调用里面的 dao层 来操作数据库 ,包括redis、mysql等通用...
  9. oracle 12.2 启用分片,关于Oracle Sharding,你想知道的都在这里
  10. Ubuntu18.04创建新的系统用户
  11. 常用选择器(CSS+JQuery)
  12. 1,3+–二苯基胍行业调研报告 - 市场现状分析与发展前景预测
  13. 小程序Windows和linux,改进后的《自动显示天气预报》小程序(Linux和Windows环境都可以)...
  14. Collection __NSArrayM: 0xxxxxxx was mutated while being enumerated.
  15. 将商品金额小写转换成大写
  16. 分布式数据:缓存技术
  17. CMOS与TTL(下)
  18. Maven的仓库(转载自Maven实战 作者许晓斌)
  19. 科目二 座椅调节 记录
  20. ‘\t‘和“\t“的区别

热门文章

  1. Mybatis Plus最新代码生成器AutoGenerator,更简单更高效!
  2. 《写给大家看的设计书(第3版)》
  3. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 E-小Y吃苹果
  4. grub2命令 linux启动盘,使用grub2制作多重启动盘(下)
  5. 网络爬虫入门——案例三:爬取大众点评的商户信息
  6. HLS-iOS视频播放服务架构深入探究(一) JAN 29TH, 2016 6:10 PM HTTP Live Streaming (HLS)
  7. 高数笔记(一):函数与极限,无穷大与无穷小
  8. python写一个爬虫、爬取网站漫画信息_python爬取漫画
  9. Ubuntu20.04系统如何安装google chrome浏览器
  10. java 邮箱找回密码_【JavaWeb】通过邮件找回密码