首页 > 其他分享 >CodeForces - 1842H

CodeForces - 1842H

时间:2024-07-25 18:41:54浏览次数:17  
标签:le 题目 int 1842H CodeForces ge

*3000,大牛题。

分析

题目的转化

首先题目中 \(x_i+x_j \le 1\) 和 \(x_i+x_j\ge 1\) 不好处理,我们不妨将 \(x_i\) 都减去 \(0.5\),结果不变,那么原题则转化成了 \(x_i+x_j\le or \ge 0\),发现现在只在乎 \(x_i\) 之间的绝对值大小关系与正负,这样就可以求出总方案数和合法的方案数,所以我们转化到了一个经典的计数问题。

动态规划

考虑按绝对值从小到大加入,首先有 \(O(n3^n)\) 的做法,设 \(dp_{S}\) 为每个数为负数正数或还没被填。
考虑枚举新添的一位,如果满足限制转移即可。
考虑优化,考虑题目性质能否帮我们优化状态,注意限制,发现 当 \(|a_i|<|a_j|\) 时,若 \(a_i+a_j\ge0\),则与 \(a_i\) 无关,\(a_j\) 必然大于 0。若 \(a_i+a_j\le 0\),则 \(a_j\) 必然小于 \(0\)。因此可以枚举当前数的正负转移即可,状态变为了元素是否在当前集合,时间复杂度降为 \(O(n2^n)\)

代码

int n,m,dp[(1<<N)],lim[N][2];
//0 小于,1 大于

void Main(){
	n=rd,m=rd,dp[0]=1;
	for(int i=1;i<=m;i++){
		int opt=rd,x=rd-1,y=rd-1;
		lim[x][opt]|=(1<<y),lim[y][opt]|=(1<<x);
	}
	for(int S=1;S<(1<<n);S++){
		for(int i=0;i<n;i++){
			if(!(S>>i&1)) continue; 
			for(int j=0;j<2;j++){
				if(lim[i][1-j]&S) continue;
				dp[S]=(dp[S]+dp[S^(1<<i)])%mod;
			}
		}
	}
	int ans=dp[(1<<n)-1];
	for(int i=1;i<=n;i++) ans=ans*qmi(i,mod-2)%mod;
	ans=ans*qmi(inv2,n)%mod;	
	cout<<ans<<endl;
}

标签:le,题目,int,1842H,CodeForces,ge
From: https://www.cnblogs.com/smilemask/p/18323903

相关文章

  • 题解:Codeforces Round 961 (Div. 2) B1&B2
    本题含有B1和B2两个难度版本。由于关系相近,我把他们放在同一篇博客中,可自行选择观看B1.Bouquet(EasyVersion)timelimitpertest:1.5secondsmemorylimitpertest:512megabytesinput:standardinputoutput:standardoutputThisistheeasyversionoftheprobl......
  • Codeforces 929 div3 D
    题目:D.TurtleTenacity:ContinualMods题目链接:https://codeforces.com/contest/1933/problem/D算法:数论、贪心。一开始没思路,后面看了别人的题解才搞懂的。思路:1.将原数组a从大到小排序后可以得到的数组b有两种情况。一种是b0!=b1,另一种则是b0=b1(下标从0开始)。对于第一......
  • 题解:Codeforces Round 961 (Div. 2) A
    A.Diagonals*timelimitpertest:1secondmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputVitaly503isgivenacheckeredboardwithasideof\(n\)and\(k\)chips.Herealizedthatallthese\(k\)chipsneedto......
  • Codeforces Round 961 (Div. 2)
    ABC没什么,除了B2还没补。主要就是这个D题。这题我基本上需要想到的都想到了,没想到的部分就是记录不合法答案而非直接记录正确答案。其实这思路也有点能够被启发的地方,就是只有某个位置前k个位置是又至少一个数字存在与我们的选择集合里的,我们才能够统计答案。也就是说,如果统计......
  • Codeforces Round 961 (Div. 2)
    A.Diagonals----------------------------题解----------------------------------注意读题,题目中只有i+j相同的格子才是一个对角线,也就是说,(1,1)(2,2)(3,3)的那条大斜线不是个对角线,如图所示这是一个3*3的图中所有的对角线,那么我们只需要如图所示,从中间往两边依次放就可以,......
  • codeforces div_2 961 题解报告
    codeforcesdiv_2961题解报告比赛链接:https://codeforces.com/contest/1995A.Diagonals题目翻译给定一个边长为\(n\)的正方形,给定\(k\),要往正方形选\(k\)个点,\(x+y\)相同的点构成对角线,问至少要几条对角线才能装下\(k\)个点。时限1s,空间限制256MB\(1\len\le100,0\l......
  • Codeforces Round 961 (Div. 2)
    A.JoeyTakesMoney--------------------------题解------------------------------------选取x和y替换掉a[i],a[j],前提是两者乘积相同,最后要求和数组最大,其实很简单,我们只需要不对另x=1y=a[j]*a[x]就行,从左到右遍历整个数组队a[i]和a[i+1]进行此操作,就可以得到我们想要的值......
  • Codeforces Round 961 (Div. 2)
    题目链接:CodeforcesRound961(Div.2)总结:B1wa两发可惜,C出得有点小慢。A.Diagonalsfag:贪心Description:给定一个\(n*n\)的棋盘,给定\(k\)个棋子,每个格子只能放一个棋子,求将棋子全部放入棋盘,至少需要占几条对角线。Solution:求最少占用,显然贪心处理,从最长的对角线开始占用,对......
  • Codeforces Round 961 (Div. 2)
    题目链接:CodeforcesRound961(Div.2)总结:B1wa两发可惜,C出得有点小慢。A.Diagonalsfag:贪心Description:给定一个n∗nn*n......
  • Codeforces Round 961 (Div. 2)
    A#include<bits/stdc++.h>usingnamespacestd;inta[200];voidsolve(){intn,k;cin>>n>>k;a[1]=n;for(intj=n-1,i=2;i<=1+(n-1)*2;i+=2,j--){a[i]=a[i+1]=j;}if(!k){cout<<0<<"\n......