首页 > 其他分享 >P7690 [CEOI2002] A decorative fence 题解

P7690 [CEOI2002] A decorative fence 题解

时间:2024-06-10 11:43:38浏览次数:25  
标签:decorative ch int 题解 sum long CEOI2002 pd now

cnblogs

如果只是询问方案数,是 P2467 [SDOI2010] 地精部落 这道题,设 \(f_{i,j,1/0}\) 表示以 \(j\) 个数中从小到大的第 \(i\) 个数处于高/低位开头的方案数。
显然有

\[\begin{aligned} \begin{cases} f_{i,j,1}=\sum_{k=1}^{i-1}f_{k,j-1,0}\\ f_{i,j,0}=\sum_{k=i}^{j-1}f_{k,j-1,1} \end{cases} \end{aligned}\]

朴素的转移是 \(O(n^3)\) 的,拿前缀和优化一下可以做到 \(O(n^2)\)。
处理出来这个后,我们利用倍增的思想查找每一位应该停留在哪个数字上,如果加上这个数字的方案数后,当前总方案数大于等于 \(C\),则这一位应该填这个数字。
具体来说,可以通过记录这一位处于高位还是低位,然后找出每一位后递归下一位来实现。具体看代码。

#include<bits/stdc++.h>
#define int long long
typedef long long ll;
typedef unsigned long long ull;
inline int read(){char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;}
const int N=25;
int n,f[N][N][N],C,ans[N];
inline void work(int x,int now,int sum,int pd){
	ans[n-sum]=x;
	if(!sum)return;
	if(pd==-1||pd==1){
		for(int i=1;i<x;++i){
			if(now+f[i][sum][0]>=C){
				work(i,now,sum-1,0);
				return;
			}
			now+=f[i][sum][0];
		}
	}
	if(pd==-1||pd==0){
		for(int i=x;i<=sum;++i){
			if(now+f[i][sum][1]>=C){
				work(i,now,sum-1,1);
				return;
			}
			now+=f[i][sum][1];
		}
	}
    \\ 递归查找,pd=1表示当前处于高位找低位,pd=0反之,pd=-1表示当前是开头,找高低位无所谓。
}
signed main(){
	// freopen("in.in","r",stdin);freopen("out.out","w",stdout);
	std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
	f[1][1][0]=1;f[1][1][1]=1;
	for(int j=2;j<=20;++j){
		for(int i=1;i<=j;++i){
			for(int k=1;k<i;++k){
				f[i][j][1]+=f[k][j-1][0];
			}
			for(int k=i;k<=j-1;++k){
				f[i][j][0]+=f[k][j-1][1];
			}
		}
	}
	int T=read();
	while(T--){
		memset(ans,0,sizeof(ans));
		n=read(),C=read();
		int st=0,zc=0;
		for(int i=1;i<=n;++i){
			zc+=f[i][n][0]+f[i][n][1];
			if(zc>=C){st=i;zc-=f[i][n][0]+f[i][n][1];break;}
		}
		work(st,zc,n-1,-1);
		std::vector<int> v;
		for(int i=1;i<=n;++i)v.push_back(i);
		v.erase(v.begin()+st-1);
		for(int i=2;i<=n;++i){
			int zc=ans[i];
			ans[i]=v[ans[i]-1];
			v.erase(v.begin()+zc-1);
		}
		for(int i=1;i<=n;++i)std::cout<<ans[i]<<' ';std::cout<<'\n';
	}
}

标签:decorative,ch,int,题解,sum,long,CEOI2002,pd,now
From: https://www.cnblogs.com/Ishar-zdl/p/18240544

相关文章

  • C++题解——3320——竞选总统(信息学奥赛一本通)
    题目描述:小明想当Y国的总统,Y国大选是按各州的投票结果来确定最终的结果的,如果得到超过一半的州的支持就可以当选,而每个州的投票结果又是由该州选民投票产生的,如果某个州超过一半的选民支持小明,则他将赢得该州的支持。现在给出每个州的选民人数,请问小明至少需要赢得多少选民的......
  • [题解]P1967 [NOIP2013 提高组] 货车运输
    P1967[NOIP2013提高组]货车运输题意简述给定一个\(N\)个节点,\(M\)条边的无向图,其中每条边有一个边权。接下来给定\(q\)次询问。每次询问给出\(x,y\),请计算\(x\)到\(y\)路径上最小边权的最大值是多少。解题思路我们对于每个连通块跑一遍最大生成树。这样整张图就成了一片森......
  • 2024年新高考1卷精选试题解答
    **(2024年新高考1卷18题)**已知函数$f(x)=\ln\fracx{2-x}+ax+b(x-1)^{3}$.(1)若$b=0$,且$f'(x)\geqslant0$,求$a$的最小值;(2)证明:曲线$y=f(x)$是中心对称图形;(3)若$f(x)>-2$当且仅当$1<x<2$,求$b$的取值范围.**解.**函数$f(x)$的定义域为$(0,2)$.(1)若$b=0$,则$f\left......
  • 题解集合
    黑暗爆炸(BZOJ)3196洛谷P3380AtCoderabc340_fabc345_fabc346_aabc346_babc346_cabc346_dabc346_eabc350_fabc350_gabc351_dabc351_fLibreOJ106......
  • [题解]P3398 仓鼠找 sugar
    P3398仓鼠找sugar题意简述给定一个\(N\)个节点的树形结构。接下来有\(q\)次询问,每次询问给定\(4\)个节点\(a,b,c,d\),请计算\(a\)到\(b\)的简单路径和\(c\)到\(d\)的简单路径是否有相交的节点。对于每个询问,输出Y/N表示答案。解题思路&Code通过手玩样例可以发现,\(a\simb\)......
  • 【题解】[CSP-J 2019] 公交换乘
    题目描述题目大意给出\(n\)次出行记录(地铁或公交车),有以下优惠方案:搭乘一次地铁后可以获得一张有效期为45分钟的优惠票,可以免费搭乘一次票价不超过该地铁票价的公交车。优惠票可以累计存储优先使用过期时间早的优惠票。思路枚举每一次出行:如果是地铁。累加花费,并记......
  • [题解]P6374 「StOI-1」树上询问
    题意简述给定一个\(N\)个节点的树,接下来有\(q\)次询问。每次询问给定\(a,b,c\),请问存在多少个节点\(i\),使得这棵树在以\(i\)为根的情况下,\(a\)和\(b\)的LCA是\(c\)。解题思路首先通过分析样例,我们发现:\(a,b\)的LCA一定在它们之间的简单路径上,所以如果\(c\)不在\(a,b\)之间的简......
  • CF1552G A Serious Referee 题解
    题目链接点击打开链接题目解法感觉很神奇的题首先把序列当成排列做首先发现只要当成\(01\)序列做就是对的为什么?你假设有数\(x<y\),你把\(\lex\)的数设成\(0\),\(>x\)且\(\ley\)的数设成\(1\),\(>y\)的数设成\(2\),然后做题目中的排序操作,如果最终序列形成逆序......
  • CF717G Underfail 题解
    题意:若干区间,区间有权值,选择一个子集,使得权值和尽量大并且每个点不被覆盖超过\(x\)次。\(n\le500\)思路:很神奇的一道题。我们考虑费用流,如果单纯的一边是区间一边是点的话其实并不好做,所以这道题我们直接建一排\(n+2\)个点,一个区间\(l,r\)就从\(l\)到\(r+1\)连......
  • CCF-GESP 等级考试 2023年9月认证C++四级真题解析
    一、单选题(每题2分,共30分)第1题⼈们所使⽤的⼿机上安装的App通常指的是()。A.⼀款操作系统B.⼀款应⽤软件C.⼀种通话设备D.以上都不对正确答案:B.⼀款应⽤软件解析:App是"Application"的缩写,中文意思是"应用",特指安装在智能手机上的第三方应用软件。这些软件通常......