zoukankan      html  css  js  c++  java
  • UVALive 6931 Can't stop playing (Regionals 2014 >> Europe

    题目

    一开始有一个双头队列,每次添加一个数(这是数是二的幂,所有数的和不大于(2^13)),由你来决定添加到队头还是队尾。如果队列里面相邻的两个数相同,设它们都是(x),那么这两个数会合并为(2x)。问所有数添加完后队列里能否只剩下一个数。

    算法

    搜索题,但是需要巧妙地记录状态!这种题不可多。

    一个显然的是,队列里不会存在相邻的三个数(a,b,c),满足(a>b,c>b)。这样的话,队列肯定是一个倒V字。

    记状态((i,j))为添加完前(i)个数,(j)是倒V左半边的上升序列状态,(j)最大是(2^{13})。通过这两个,我们可以算出倒V右半边的序列状态!

    这样的话,时间复杂度就是(O(n 2^{13}))

    代码

    官方的标程有点点小错误。UVALive上的数据也错了。但当时比赛的数据是正确的!

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <assert.h>
    using namespace std;
    
    template <class T>
    void tension(T &a, const T &b) {
    	if (b < a) a = b;
    }
    
    template <class T>
    void relax(T &a, const T &b) {
    	if (b > a) a = b;
    }
    
    typedef long long i64;
    
    #ifndef ONLINE_JUDGE
    #define ep(...) fprintf(stderr, __VA_ARGS__)
    #else
    #define ep(...) assert(true)
    #endif
    
    int n;
    int sum[1003], A[1003];
    bool vis[1003][(1 << 13) + 1];
    char ans[1003];
    int highBit[1 << 14];
    
    int place(int a, int b, int x) {
    	if (highBit[a] > highBit[b]) {
    		int tmp = highBit[a];
    		a -= tmp;
    		b += tmp;
    	}
    	if (a && (a & -a) < x) return -1;
    	a += x;
    	while (highBit[a] == highBit[b]) {
    		int tmp = highBit[a];
    		a += tmp;
    		b -= tmp;
    	}
    	return a;
    }
    
    bool dfs(int k, int s1) {
    	int s2 = (k ? sum[k - 1] : 0) - s1;
    	
    	if (k == n) {
    		if (highBit[s1] > highBit[s2]) {
    			int tmp = highBit[s1];
    			s1 -= tmp;
    			s2 += tmp;
    		}
    		if (highBit[s2] > highBit[s1]) {
    			int tmp = highBit[s2];
    			s2 -= tmp;
    			s1 += tmp;
    		}
    		if (s1 == (s1 & -s1) && s2 == 0) return true;
    		if (s2 == (s2 & -s2) && s1 == 0) return true;
    		return false;
    	}
    	
    	if (vis[k][s1]) return false;
    	vis[k][s1] = true;
    	
    	int x = A[k];
    	int tmp = place(s1, s2, x);
    	if (tmp != -1 && dfs(k + 1, tmp)) {
    		//ep("l (%d, %d) %d ->
    ", s1, s2, x);
    		ans[k] = 'l';
    		return true;
    	}
    	tmp = place(s2, s1, x);
    	if (tmp != -1 && dfs(k + 1, sum[k] - tmp)) {
    		//ep("r (%d, %d) %d ->
    ", s1, s2, x);
    		ans[k] = 'r';
    		return true;
    	}
    	return false;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("input.txt", "r", stdin);
    	//freopen("all.in", "r", stdin);
    	freopen("output.txt", "w", stdout);
    #endif
    	for (int i = 1; i < 1 << 14; i ++) 
    		if ((i & -i) == i) highBit[i] = i;
    		else highBit[i] = highBit[i - 1];
    
    	scanf("%*d");
    	for (int cases = 1; scanf("%d", &n) == 1; cases ++) {
    		//ep("Case %d: ", cases);
    		for (int i = 0; i < n; i ++) {
    			scanf("%d", A + i);
    			sum[i] = A[i];
    			if (i) sum[i] += sum[i - 1];
    		}
    		
    		//memset(vis, 0, sizeof vis);
    		for (int i = 0; i < n; i ++)
    			memset(vis[i], 0, sizeof vis[i]);
    		if (dfs(0, 0)) {
    			ans[n] = '';
    			printf("%s
    ", ans);
    		}
    		else printf("no
    ");
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    C#使用Json.Net遍历Json
    晓晨高效IP提取工具 附源码
    JavaScript原生秒表、计时器
    网盘直链工具 winform版 V1.0
    【架构】RPC 使用 Haproxy、keepalive作为负载均衡
    【架构】Google的大规模集群管理工具Borg
    【Networking】gRPC golang 相关资料
    【Linux】find grep 联合使用 过滤所有子目录、文件
    【Storage】Ubuntu LVM 安装配置
    【Ansible】SSH Error: ssh_exchange_identification: Connection closed by remote host
  • 原文地址:https://www.cnblogs.com/wangck/p/4528905.html
Copyright © 2011-2022 走看看