首页 > 其他分享 >[Tkey] A decorative fence

[Tkey] A decorative fence

时间:2024-06-17 15:44:45浏览次数:10  
标签:decorative le fence int Rank cases now Tkey define

还是看看简单而富有美感的爆搜吧
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define tests int cases;cin>>cases;while(cases--)
int n,l;
vector<int> e;bool vis[21];int cnt=0;
void dfs(int p){
	if(cnt==l) return;
	if(p>n){
		cnt++;
		if(cnt==l){
			for(int i:e) cout<<i<<" ";
			cout<<endl;
		}
		return;
	}
	for(int i=1;i<=n;++i){
		if(!vis[i]){
			if(e.size()<=1){
				e.push_back(i);vis[i]=1;
				dfs(p+1);
				e.pop_back();vis[i]=0;
			}
			else if((*(e.end()-1)>*(e.end()-2)&&*(e.end()-1)>i)||
			(*(e.end()-1)<*(e.end()-2)&&*(e.end()-1)<i)){
				e.push_back(i);vis[i]=1;
				dfs(p+1);
				e.pop_back();vis[i]=0;
			}
		}
	}
}
signed main(){
	tests{
		e.clear();cnt=0;
		cin>>n>>l;
		dfs(1);
	}
}

思路

这题爆搜肯定是不行,考虑一个事实:

假设 1xxxx 是 \(Rank=a\) 的一种方案,1yyyy 是 \(Rank=b\) 的另一种方案,而目标 \(Rank\ k\) 满足 \(a\le k\le b\),则有 \(Rank=k\) 的方案的首位一定是 \(1\).

跟我们猜数是一样的. 假设有个数给你猜,\(114\) 小了,\(191\) 大了,那你肯定知道这个数最高位是什么了.

所以我们就开个数组来转移并维护这个 \(Rank\) 值.

注意到 \(Rank\) 并不是非常好维护,我们可以考虑维护每种情况的方案数,然后按字典序从小到大依次加起来,这样就是 \(Rank\) 值了.

设 \(f[i][j][k]\) 为放入前 \(i\) 块木板构成的栅栏,当第 \(i\) 块木板的 \(Rank=j\) 时的方案数. 注意到这样还是不好维护,因为要考虑是高低高还是低高低,那么再开一维 \(k\) 来表示这个. \(k=1\) 时 \(1\) 为高,反之亦然.

那么这个转移非常好写,也不是本题的难点.

\[\begin{cases}f[i][j][1]=\sum_{1\le k\le j-1} f[i-1][k][0]\\f[i][j][0]=\sum_{j\le k\le i-1} f[i-1][k][1]\end{cases} \]

这里唯一需要注意的是求和的范围. 因为我们这个 \(k\) 指代的是 \(Rank=k\),而且会涉及到选高的还是选低的的问题,也就有了 \(k\) 的范围的差异.

那么还很容易注意到,这个转移和 \(n,m\) 完全没有关系,所以从多测里提出来作为初始化.

然后就是按上面的思想来逼近我们要求的答案.

先来确定第一位吧,我们需要做的就是遍历每个 \(1\le i\le n\),只要有 \(\sum^{i}_{j=1}(f[n][j][0]+f[n][j][1])> m\),就能判定 \(j-1\) 是我们要求的那个第一位.

很显然,当我们之前几位选过某个数字,那我们就不能再选了,因此在之后的几次逼近中,我们还需要判断当前 \(Rank\) 的板子是不是已经被使用过了,然后进行类似的判断即可.

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define speed ios::sync_with_stdio(false);
#define tests int cases;cin>>cases;while(cases--)
#define clear(i) memset((i),0,sizeof (i))
int f[21][21][2];   //now fences have n planks, and the leftest planks ranking j
			        //k=0 means leftest is shorter,else taller
int n,m;
bool vis[21];
/*
f[i][j][1]=sum k{from 1 to j-1} f[i-1][k][0]
f[i][j][0]=sum k{from j to i-1} f[i-1][k][1]
*/
void prework(){
	f[1][1][1]=1;f[1][1][0]=1;
	for(int i=2;i<=20;++i){
		for(int j=1;j<=i;++j){
			for(int k=1;k<=j-1;++k){
				f[i][j][1]+=f[i-1][k][0];
			}
			for(int k=j;k<=i-1;++k){
				f[i][j][0]+=f[i-1][k][1];
			}
		}
	}
}
signed main(){
	prework();
	speed tests{
		cin>>n>>m;
		clear(vis);
		int now,last;
		for(int i=1;i<=n;++i){
			if(f[n][i][1]>=m){
				last=i;now=1;break;
			}
			else{
				m-=f[n][i][1];
			}
			if(f[n][i][0]>=m){
				last=i;now=0;break;
			}
			else{
				m-=f[n][i][0];
			}
		}
		cout<<last<<" ";
		vis[last]=true;
		for(int i=2;i<=n;++i){
			now=1-now;int rank=0;
			for(int len=1;len<=n;++len){
				if(vis[len]) continue;
				rank++;
				if((now==0 and len<last)or(now==1 and len>last)){
					if(f[n-i+1][rank][now]>=m){
						last=len;break;
					}
					else{
						m-=f[n-i+1][rank][now];
					}
				}
			}
			vis[last]=true;
			cout<<last<<" ";
		}
		cout<<endl;
	}
}

标签:decorative,le,fence,int,Rank,cases,now,Tkey,define
From: https://www.cnblogs.com/HaneDaCafe/p/18252544

相关文章

  • P7690 [CEOI2002] A decorative fence 题解
    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}......
  • [Tkey] 生日礼物
    题意简述彩珠有\(n\)个\(k\)种,每个珠子都有一个坐标\(p_{i}\),求最小的区间长度,使得这个区间包含全部的\(k\)种彩珠.分析发现我们可以维护每一种颜色的最近出现坐标.因为是最近的出现坐标,所以离现在的距离(即答案)一定是更优的,那么我们用这个值来更新答案一定就是最优的.......
  • P2731 [USACO3.3] 骑马修栅栏 Riding the Fences
    原题链接题解贪心走最小的点,由于每个点都有偶数条边,所以能进入就一定能出去code#include<bits/stdc++.h>usingnamespacestd;structnode{intto,id;};vector<node>G[505];intlate[505]={0};intvis[1044]={0};intstart=1,finish;stack<int>st;intn,m;......
  • [Tkey] CodeForces 1267G Game Relics
    太神了这题,膜拜出题人orz。思考一首先是大家都提到的一点,先抽卡再买。这里来做个数学分析。假设我们还剩\(k\)种没有买,其实我们是有式子来算出它的花费期望的。WIKI上提到,假设一个事件的概率为\(p\),则遇到它的期望为\(\frac{1}{p}\),因此,对于这个题,抽到一个新物品的概率显......
  • 翻译《The Old New Thing》- Hotkeys involving the Windows logo key are reserved b
    HotkeysinvolvingtheWindowslogokeyarereservedbythesystem-TheOldNewThing(microsoft.com)https://devblogs.microsoft.com/oldnewthing/20071130-00/?p=24333RaymondChen 2007年11月30日Windows徽标键的热键由系统保留        系统保留了......
  • c# Dictionary<TKey,TValue>.TryAdd
    原文链接:https://learn.microsoft.com/zh-cn/dotnet/fundamentals/code-analysis/quality-rules/ca1864Dictionary<TKey,TValue>.ContainsKey(TKey) 和 Dictionary<TKey,TValue>.Add 都执行查找操作,这是冗余设置。如果字典中已存在键,Dictionary<TKey,TValue>.Add 也会引发异......
  • openGauss plpython-fenced模式
    PLPythonFenced模式在fenced模式中添加plpython非安全语言。在数据库编译时需要将python集成进数据库中,在configure阶段加入--with-python选项。同时也可指定安装plpython的python路径,添加选项--with-includes='/python-dir=path'。在启动数据库之前配置GUC参数unix_socket_dir......
  • 52 Things: Number 43: Describe some basic (maybe ineffective) defences against s
    52Things:Number43:Describesomebasic(maybeineffective)defencesagainstsidechannelattacksproposedintheliteratureforAES52件事:第43件:描述AES文献中提出的针对侧信道攻击的一些基本(可能无效)防御措施 Thisisthelatestinaseriesofblogpoststoa......
  • 52 Things: Number 44: Describe some basic (maybe ineffective) defences against s
    52Things:Number44:Describesomebasic(maybeineffective)defencesagainstsidechannelattacksproposedintheliteratureforECC.52件事:第44件:描述文献中为ECC提出的一些针对侧信道攻击的基本(可能无效)防御措施。 Thisisthelatestinaseriesofblogposts......
  • 52 Things: Number 45: Describe some basic (maybe ineffective) defences against s
    52Things:Number45:Describesomebasic(maybeineffective)defencesagainstsidechannelattacksproposedintheliteratureforRSA.52件事:第45件:描述RSA文献中提出的针对侧信道攻击的一些基本(可能无效)防御措施。 Thisisthelatestinaseriesofblogpostst......