首页 > 其他分享 >「题解」Codeforces 1730F Almost Sorted

「题解」Codeforces 1730F Almost Sorted

时间:2022-10-21 15:02:36浏览次数:55  
标签:typedef ch 1730F leq Almost 题解 int read include

给定一个长度为 \(n\) 的置换 \(p\),以及一个正整数 \(k\).

对于一个置换 \(q\),要求对于所有满足 \(1\leq i<j\leq n\) 的 \(i,j\),有以下不等式成立:

\[p_{q_i}\leq p_{q_j}+k \]

现在请求出满足条件的置换 \(q\) 中,逆序对数最小的 \(q\),它逆序对数是多少。

\(1\leq n\leq 5000,1\leq k\leq 8\).

相当于要对 \(p\) 进行重排,如果将某个前缀出现过的 \(p\) 看作一个二进制数,那么即为要求最高的 \(1\) 和最低的 \(0\) 之间相差不能超过 \(k\).所以我们知道如果填了 \(i\),那么 \(<i-k\) 的那些数一定已经填过了。所以先 \(\mathcal{O}(n^2)\) 把 \(<i-k\) 的那些逆序对给统计上。

那么就好 dp 了,\(f_{i,S}\) 表示从低到高填到了 \(i\),然后 \(i\) 前面 \(k\) 个数填的状态是 \(S\),只记前 \(k\) 个是因为由于条件的限制 \(<i-k\) 的都一定已经填过了。

这样时间复杂度就是 \(\mathcal{O}(n^2+nk^22^k)\),因为转移的时候枚举下一个填啥是 \(\mathcal{O}(k)\) 的,还有一个暴力 \(\mathcal{O}(k)\) 计算逆序对贡献。

#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<ctime>
#include<random>
#include<assert.h>
#define pb emplace_back
#define mp make_pair
#define fi first
#define se second
#define dbg(x) cerr<<"In Line "<< __LINE__<<" the "<<#x<<" = "<<x<<'\n';
#define dpi(x,y) cerr<<"In Line "<<__LINE__<<" the "<<#x<<" = "<<x<<" ; "<<"the "<<#y<<" = "<<y<<'\n';
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>pii;
typedef pair<ll,int>pli;
typedef pair<ll,ll>pll;
typedef pair<int,ll>pil;
typedef vector<int>vi;
typedef vector<ll>vll;
typedef vector<pii>vpii;
typedef vector<pil>vpil;
template<typename T>T cmax(T &x, T y){return x=x>y?x:y;}
template<typename T>T cmin(T &x, T y){return x=x<y?x:y;}
template<typename T>
T &read(T &r){
	r=0;bool w=0;char ch=getchar();
	while(ch<'0'||ch>'9')w=ch=='-'?1:0,ch=getchar();
	while(ch>='0'&&ch<='9')r=r*10+(ch^48),ch=getchar();
	return r=w?-r:r;
}
template<typename T1,typename... T2>
void read(T1 &x,T2& ...y){read(x);read(y...);}
const int mod=998244353;
inline void cadd(int &x,int y){x=(x+y>=mod)?(x+y-mod):(x+y);}
inline void cdel(int &x,int y){x=(x-y<0)?(x-y+mod):(x-y);}
inline int add(int x,int y){return (x+y>=mod)?(x+y-mod):(x+y);}
inline int del(int x,int y){return (x-y<0)?(x-y+mod):(x-y);}
const int inf=0x3f3f3f3f;
inline int bit(int x){
	return 1<<(x-1);
}
inline int all(int x){
	return (1<<x)-1;
}
const int N=5010;
int n,k,p[N],vis[N],c[N];
int f[N][260],ans;
int calc(int x,int s,int i){
	int sum=vis[x]>vis[x-i];
	for(int j=1;j<=k&&x-j>=1;j++)
		if(bit(j)&s)
			if(vis[x-j]>vis[x-i])
				++sum;
	for(int j=k+1;x-j>=1&&j<=k+i;j++)
		if(vis[x-j]>vis[x-i])
			++sum;
	return sum;
}
signed main(){
	#ifdef do_while_true
//		assert(freopen("data.in","r",stdin));
//		assert(freopen("data.out","w",stdout));
	#endif
	read(n,k);
	for(int i=1;i<=n;i++)read(p[i]),vis[p[i]]=i;
	for(int i=1;i<=n;i++)
		for(int j=1;j<i-k;j++)
			if(vis[j]>vis[i])
				++ans;
	memset(f,0x3f,sizeof(f));
	f[0][(1<<k)-1]=0;
	for(int i=0;i<=n;i++)
		for(int s=0;s<(1<<k);s++)if(f[i][s]!=inf){
			for(int j=1;j<=k;j++)
				if(!(bit(j)&s)){
					cmin(f[i][s|(1<<(j-1))],f[i][s]+calc(i,s,j));
				}
			for(int j=1;j<=k+1&&i+j<=n;j++){
				if(j<=k && !(bit(k-j+1)&s))break;
				int to=((s<<j)|bit(j))&all(k);
				cmin(f[i+j][to],f[i][s]+calc(i+j,to,0));
			}
		}
	cout << f[n][(1<<k)-1]+ans << '\n';
    #ifdef do_while_true
//		cerr<<'\n'<<"Time:"<<1.0*clock()/CLOCKS_PER_SEC*1000<<" ms"<<'\n';
	#endif
	return 0;
}

标签:typedef,ch,1730F,leq,Almost,题解,int,read,include
From: https://www.cnblogs.com/do-while-true/p/16813470.html

相关文章

  • accoders NOI #5014. 树上询问(query) 题解
    昨天刚刚做过一道类似的题,没想到在模拟赛当中出现了。题目描述有一棵\(n\)个结点的树,有\(m\)次询问,每次询问给你两个整数\(l,r\),问存在多少个整数\(k\)使得从\(l......
  • 顺丰科技智慧物流校园技术挑战赛 一份题解
    我只是做了代码裁缝的角色罢了目录​​试题地址​​​​1​​​​2​​​​3​​​​4​​​​5​​试题地址​​https://leetcode.cn/contest/sf-tech/​​1DFS判定有向图......
  • 题解 P5527 [Ynoi2012] NOIP2016 人生巅峰
    人生第一道Ynoi,同时也是1k通过。不卡常不难写,小清新Ynoi真的不多见了。前置知识:抽屉原理,树状数组,bitset,动态规划基础。首先考虑一个事实,当这个区间够长是必然有解的......
  • CF645E Intellectual Inquiry 题解
    传送门|无耻地宣传我的博客(矩乘代码在最后)看一眼题,没什么思路,那大概就是个dp了。先求已知序列的方案数。考虑怎么设计状态。因为本质不同,如果设\(f[i]\)表示,......
  • electron升级到20版本后,禁用第三方cookie、跨域问题解决方法
    最近公司的electron项目从13升级到最新的20版本,导致qq登录失效问题,特此记录1.qq扫码登录失效升级后之前的老版本可以扫码登录,但是新版本扫码登录后,页面直接刷新,没有登录......
  • P8251 [NOI Online 2022 提高组] 丹钓战 题解
    本文写于2022-03-2614:45:14。原博客地址题目链接算法(倍增)$O((n+q)\logn)$为简便,把元素$(a_i,b_i)$称为元素$i$。对一个区间$[l,r]$模拟一遍,从空栈开始,头......
  • wget --no-check-certificate 问题解决
    很多时候一些老旧机器因为ca证书的问题,造成下载异常,实际上解决方法很简单,一种方法是参考提示就行了解决方法添加--no-check-certificate使用.wgetrc文件(以后都就可......
  • AcCoders 10477:【省选基础数据结构 树链剖分】【GDOI2016】疯狂动物城 题解
    算法:树链剖分,可持久化线段树。题目大意给定\(n\)个结点的一棵树,\(m\)次操作,操作有三种:将\(x\)至\(y\)最短路径上的所有点的权值加上\(delta\)。对于\(x\)至......
  • 题解 For Problem. 完全参差序列
    Problem.完全参差序列题目背景2022年,南京师范大学迎来了120周年校庆,值此120周年校庆筹备工作全面启动之际,学校诚邀海内外校友、社会贤达、各界人士壬寅中秋相聚金陵,......
  • CF1742E Scuza题解
    CF1742EScuza题意简述\(t\)组数据,对于每组数据:有\(n\)级台阶,每级台阶比上一级高\(a_i\)米。有\(q\)次询问,每次询问给出一个腿长\(k\),问在每次跨上的高度不大......