codeforces585D. Lizard Era: Beginning

传送门:http://codeforces.com/problemset/problem/585/d

思路:中途相遇法

前一半暴力枚举,后一半暴力枚举,在hash表里查找是否有合法的方案即可,输出方案在hash表存一个3进制数即可

#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn=30,mod=9999993,base=500000000,maxt=600010,inf=1e9;
typedef long long ll;
using namespace std;
int n,m,ans,sta1,sta2,pow[maxn];
struct data{int a,b,c;}p[maxn];

struct hash{
    int pre[maxt],now[mod+10],tot,val[maxt][3],sta[maxt];
    void insert(int a,int b,int c,int st){
        int x=(a-b+base)%mod;
        for (int y=now[x];y;y=pre[y])
            if (val[y][0]==a&&val[y][1]==b&&val[y][2]==c) return;
        pre[++tot]=now[x],now[x]=tot,val[tot][0]=a,val[tot][1]=b,val[tot][2]=c,sta[tot]=st;
    }
    void query(int a,int b,int c,int st){
        int x=(b-a+base)%mod,tmp=-inf*2,t1;
        for (int y=now[x];y;y=pre[y])
            if (val[y][1]-val[y][2]==c-b)
                if (val[y][0]>tmp) tmp=val[y][0],t1=sta[y];
        if (tmp+a>ans) ans=tmp+a,sta1=st,sta2=t1;
    }
}T;

void dfs(int k,int lim,int a,int b,int c,int code,int op){
    if (k==lim+1){
        if (!op) T.insert(a,b,c,code);
        else T.query(a,b,c,code);
        return;
    }
	dfs(k+1,lim,a+p[k].a,b+p[k].b,c,code*3,op);
    dfs(k+1,lim,a+p[k].a,b,c+p[k].c,code*3+1,op);
    dfs(k+1,lim,a,b+p[k].b,c+p[k].c,code*3+2,op);
}

int main(){
    scanf("%d",&n),m=(n+1)>>1,ans=-inf;
    pow[0]=1;for (int i=1;i<=m+1;i++) pow[i]=pow[i-1]*3;
    for (int i=1;i<=n;i++) scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c);
    dfs(m+1,n,0,0,0,0,0),dfs(1,m,0,0,0,0,1);
    if (ans==-inf){puts("Impossible");}
    else{
        for (int i=1;i<=m;i++){
            int t=(sta1/pow[m-i])%3;
			if (t==0) puts("LM");
			if (t==1) puts("LW");
            if (t==2) puts("MW");
        }
        for (int i=m+1;i<=n;i++){
            int t=(sta2/pow[n-i])%3;
            if (t==0) puts("LM");
			if (t==1) puts("LW");
            if (t==2) puts("MW");
        }
    }
    return 0;
}


转载于:https://www.cnblogs.com/thythy/p/5493508.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值