• TopCoder14580: EllysRPS


    题意

    (yyb)要去与(m)((mle100))个人玩游戏
    由于(yyb)忙着切大火题,他没有太多的精力浪费在游戏上
    所以仁慈的(yyb)决定放(m)个人一条生路,不吊打他们
    然而(yyb)为了维护自己红太阳的形象,不能输,所以他希望与每个人玩游戏都能是平局

    游戏很简单,就是石头剪刀布,(yyb)会与每个人玩(n(nle 20))
    只要双方赢的次数相同就视为平局

    (yyb)非常的强,所以大家每一场比赛想出什么(yyb)一眼就看出来了
    每个人的策略都是一个长度为(n)的序列
    然后他觉得能用同一个长度为(n)的策略序列与每个人打平局
    然而(yyb)并不满足与这些,他想知道自己有多少种方式打平,这样他就能知道别人比自己弱多少,从而增长自己的淫威

    正如大家所知,(yyb)秒题入魔,懒得去想这个(naive)的比赛
    所以请比他弱的你来帮他求出这个方案数

    Sol

    (meet in the midlle)
    爆搜,把状态开(vector)压进(map)查询

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    typedef vector <int> vi;
     
    IL int Input(){
        RG int x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int win[3][3] = {{0, -1, 1}, {1, 0, -1}, {-1, 1, 0}};
    int n, m, a[105][25], b[25], mid;
    vi tmp;
    map <vi, int> t;
    ll ans;
    
    IL void Record(){
    	tmp.clear();
    	for(RG int i = 1; i <= m; ++i){
    		RG int cnt = 0;
    		for(RG int j = 1; j <= mid; ++j) cnt += win[a[i][j]][b[j]];
    		tmp.push_back(cnt);
    	}
    	++t[tmp];
    }
    
    IL void Dfs1(RG int l){
    	if(l > mid){
    		Record();
    		return;
    	}
    	for(RG int i = 0; i < 3; ++i) b[l] = i, Dfs1(l + 1);
    }
    
    IL void Calc(){
    	tmp.clear();
    	for(RG int i = 1; i <= m; ++i){
    		RG int cnt = 0;
    		for(RG int j = mid + 1; j <= n; ++j) cnt -= win[a[i][j]][b[j]];
    		tmp.push_back(cnt);
    	}
    	ans += t[tmp];
    }
    
    IL void Dfs2(RG int l){
    	if(l > n){
    		Calc();
    		return;
    	}
    	for(RG int i = 0; i < 3; ++i) b[l] = i, Dfs2(l + 1);
    }
    
    IL ll Solve(){
    	mid = (1 + n) >> 1;
    	Dfs1(1), Dfs2(mid + 1);
    	return ans;
    }
    
    class EllysRPS{
    public:
    	ll getCount(vector <string> s){
    		m = s.size(), n = s[0].size();
    		for(RG int i = 1; i <= m; ++i)
    			for(RG int j = 1; j <= n; ++j)
    				if(s[i - 1][j - 1] == 'R') a[i][j] = 0;
    				else a[i][j] = (s[i - 1][j - 1] == 'S') + 1;
    		return Solve();
    	}
    };
    
  • 相关阅读:
    树状数组基本操作
    P1802 5倍经验日 题解
    函数学习总结
    康托展开
    中国电信CDMA无线上网卡短信收发
    报错:无法获取实体类XXX对应的表名!
    javajvisualvm远程监控云服务器上的Tomcat8.5
    服务器防火墙开放端口
    报错:列"AGENT_ENTITY_NAME"的值太大(实际值: 60,最大值50) oracle VARCHAR2和NVARCHAR2的区别
    linux中查看端口是否被占用lsof i:port
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8940024.html
Copyright © 2020-2023  润新知