• atcoder Keyence Programming Contest 2020 D


    atcoder Keyence Programming Contest 2020 D - Swap and Flip 2020腾讯暑假实习笔试(状压dp or 状压乱搞)

    题意

    一张牌有正反两面,都有数字,有操作交换相邻两张卡牌,交换的时候两张牌都会翻转,问最少操作次数使得卡牌满足数字非降(n<=18)

    分析

    n<=18明示状压,首先要看什么样的序列是合法的
    我们以0 1表示卡牌相对于初始状态是否翻转

    1.1的数量为偶数,自己模拟一下就懂了
    2.卡牌移动的距离和卡牌在那个位置上的正反是有关系的,奇数距离肯定是反面,偶数是正面

    我们可以暴力枚举每张卡牌的01状态,一共(2^n)种状态,然后以以上条件判断合法后进行匹配,显然原序列每张牌和最左边一张可以匹配上的牌匹配是最优的,得出卡牌交换后每个序号所在的位置后,逆序数就是最小交换次数
    复杂度(2^n*n^2)
    因为本人状压比较拉胯,笔试的时候随便乱搞,估计是数据太水过了。。

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define F first
    #define S second
    #define mkp make_pair
    #define pii pair<int,int>
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int maxn=2e5+5;
    pair<int,int>pre[maxn],after[maxn];
    int n;
    int vis[maxn],a[maxn],b[maxn],p[maxn];
    int solve(int s){
    	int cnt=0;
    	for(int i=0;i<n;i++)vis[i]=0;
    	for(int i=0;i<n;i++){
    		if((s>>i)&(1)){
    			cnt++;
    			pre[i]=mkp(b[i],1);
    			after[i]=pre[i];
    		}
    		else {
    			pre[i]=mkp(a[i],0);
    			after[i]=pre[i];
    		}
    	}
    	if(cnt&1)return inf;
    	cnt=0;
    	sort(after,after+n);
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			if(after[j].first==pre[i].first&&((abs(i-j)%2)==pre[i].second)&&vis[j]==0){
    				vis[j]=1,cnt++,p[i]=j;
    				break;
    			}
    		}
    	}
    	if(cnt!=n)return inf;
    	int ans=0;
    	for(int i=0;i<n;i++){
    		for(int j=i+1;j<n;j++){
    			if(p[j]<p[i])ans++;
    		}
    	}
    
    	return ans;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=0;i<n;i++)scanf("%d",&a[i]);
    	for(int i=0;i<n;i++)scanf("%d",&b[i]);
    	int ans=inf;
    	for(int i=0;i<1<<n;i++){
    		ans=min(ans,solve(i));
    	}
    	printf("%d
    ",ans==inf?-1:ans);
    }
    
    
  • 相关阅读:
    面试题58:翻转字符串
    面试题57_2:和为S的连续正数序列
    面试题57:和为S的数字
    面试题56:数组中数字出现的次数
    面试题55_2:平衡二叉树
    面试题54:二叉搜索树的第k大节点
    面试题55_1:二叉树的深度
    tortoisegit 本地创建的分支 push github
    TortoiseGit 拉取分支
    tortoiseGIT 本地分支创建合并
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/12811825.html
Copyright © 2020-2023  润新知