bzoj1004[HNOI2008] Cards

2024-05-11 23:58
文章标签 cards hnoi2008 bzoj1004

本文主要是介绍bzoj1004[HNOI2008] Cards,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:bzoj1004
题目大意:
有3种颜色:红色,蓝色,绿色。要求染出Sr张红色,Sb张蓝色,Sg张绿色。M种不同的洗牌法,这里问有多少种不同的染色方案。两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方法可以使用多次)洗成另一种。要求出答案除以P的余数(P为质数)。100%数据满足 Max{Sr,Sb,Sg}≤20;m≤60,m+1<p<100
输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代替,且对每种洗牌法,都存在一种洗牌法使得能回到原状态。

题解:
置换+dp

对于每个置换就暴力找循环节。然后f[i][j][k]分别表示用了i张红色,j张蓝色,k张绿色的方案,dp一下就好了。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 70bool vis[N];int sa,sb,sc,num;
int mod,a[N],g[N],f[N][N][N];
void dp()
{memset(f,0,sizeof(f));int p,i,j,k;f[0][0][0]=1;for (p=1;p<=num;p++)for (i=sa;i>=0;i--)for (j=sb;j>=0;j--)for (k=sc;k>=0;k--){if (i>=g[p]) f[i][j][k]=(f[i][j][k]+f[i-g[p]][j][k])%mod;if (j>=g[p]) f[i][j][k]=(f[i][j][k]+f[i][j-g[p]][k])%mod;if (k>=g[p]) f[i][j][k]=(f[i][j][k]+f[i][j][k-g[p]])%mod;}
}
int qpow(int x,int tt)
{int ret=1;while (tt){if (tt&1) ret=(ret*x)%mod;x=(x*x)%mod;tt>>=1;}return ret;
}
int main()
{freopen("a.in","r",stdin);freopen("a.out","w",stdout);int m,n,ans,i,j;scanf("%d%d%d%d%d",&sa,&sb,&sc,&m,&mod);n=sa+sb+sc;ans=0;m++;for (i=1;i<=m;i++){num=0;if (i<m) for (j=1;j<=n;j++) {scanf("%d",&a[j]);vis[j]=true;}else for (j=1;j<=n;j++) a[j]=j,vis[j]=true;for (j=1;j<=n;j++) if (vis[j]){int x=j,cnt=0;while (vis[x]){vis[x]=false;cnt++;x=a[x];}g[++num]=cnt;}dp();ans=(ans+f[sa][sb][sc])%mod;}ans=(qpow(m,mod-2)*ans)%mod;//G是置换群 所以|G|是指置换的个数 所以是m而不是元素n的个数printf("%d\n",ans);return 0;
}

天天吞我题解好气啊

这篇关于bzoj1004[HNOI2008] Cards的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/981021

相关文章

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

【HDU】4876 ZCC loves cards 暴力

传送门:【HDU】4876 ZCC loves cards 题目分析: 这题无力吐嘈。。。。能想到的优化都用上吧。。。 代码如下: #include <cstdio>#include <cstring>#include <algorithm>using namespace std ;#define REP( i , n ) for ( int i =

poj 1721 CARDS(置换)

http://poj.org/problem?id=1721 大致题意:原始序列通过洗牌机洗牌s次后变为当前序列,已知当前序列,求原始序列。 在置换群快速幂运算 研究与探讨中最后有详解,有两种解法,一种是求出置换的长度a(即一副牌洗a次后变回原来的位置),现已知原始序列置换s次变为当前序列,那么当前序列再置换a-s次就是原始序列了。求a就是直接模拟每个置换的过程,直到某序列与当前序

题解:P3569 [POI2014] KAR-Cards

题意 有 n n n 个元素,第 i i i 个元素有两个权值 a i a_i ai​ 和 b i b_i bi​;有 m m m 次操作,每次操作会交换两个元素的位置,且都需要回答:是否存在一种方案,使得每个元素各选择一个权值后,组成的序列从左到右单调不降。 解法 完全可以把交换操作看作两次单点修改,每次只需要考虑一个元素的变化对答案的影响即可。对于一个区间中的元素,显然开

[LightOJ 1364] Expected Cards (高维期望DP)

LightOJ - 1364 一副扑克牌,不断地从中抽牌 要求四种花色都至少要有给定的张数 其中如果抽到了王牌,可以将其变为任意花色 求满足条件时,抽出的期望张数 刚开始想错了,两张王牌并非在一开始就给定了 而是在游戏中可以视当前情况选择着变的 这两种方式是不一样的 由于牌数其实并不会很多, 复杂度乘一乘发现才 107 10^7级别的,所以直接暴力DP 将两张王牌当

HDU 1535 Invitation Cards 2次Dijkstra来回最短路

题目来源:HDU 1535 Invitation Cards 题意:从1派学生到2-n这n-1个点  求去并且回来的最短路 就是1到各点的最短路之和和各点到1的最短路之和 给的是有向图 思路:对于1到各个点的最短路直接Dijkstra求出无压力 然后各个点到1的最短路可以反向建图后再求一次从1到各个点的最短路 对于很多点到一个点的情况可以考虑反向建图 转变成单源最短路 #include <

Codefores 398A Cards(贪心+暴力)

题目链接:Codefores 398A Cards 题目大意:给出a和b,表示说有a个“o”的卡和b个“x”的卡,将这a+b个卡片排成一个序列,每连续的k个相同的卡片为一个数,表示k^2,如果是o,则是+k^2,否则-k^2。要求找到一个序列使得最后的结果尽量大。 解题思路:一开始一直想用贪心的思想直接构造出来,后来和小伙伴一人想了一种构造方法,但是又互相推翻了。。。。不过很快就想

hdu 4610 Cards(暴力+miller-rabin)

题目链接:hdu 4610 Cards 解题思路 用素数筛选法先预处理出每个数的因子个数,因子和。因子个数肯定小于1e6,可以根据预处理的素数表直接判断是否为素数,但是因子和可能到达4百多万,所以直接用miller-rabin直接判素数。 判断因子积是否是平方和的部分,考虑因子个数,如果因子个数为奇数(即该数为平方数),则sqrt(i)必须是平方数才行。如果因子个数为偶数,则cnt/2为偶数

zoj3380 Patchouli's Spell Cards

Patchouli's Spell Cards Time Limit: 7 Seconds Memory Limit: 65536 KB Patchouli Knowledge, the unmoving great library, is a magician who has settled down in the Scarlet Devil Mansion (紅魔館)

Poj 1511 Invitation Cards -- spfa

/*方法:spfa算法。注意在存边的时候,此题在数据上卡掉了vector,可以用邻接表。因为本题要计算人去发传单和回来的最小花费之和,所以需要两次spfa。*/#include<cstdio>#include<algorithm>#include<queue>#include<cstring>#define ll long longusing namespace std;#de