码迷,mamicode.com
首页 > 其他好文 > 详细

[codeforces] 585D Lizard Era: Beginning || 双向dfs

时间:2017-12-10 23:00:02      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:make   long   iterator   oid   双向   span   har   表示   vector   

原题

有n(n<=2)个任务和三个人,每次任务给出每个人能得到的值,每次任务选两个人,使n个任务结束后三个人得到的值是一样的。输出每次要派哪两个人,如果不行输出Impossible。


n<=25,3^25肯定不行,所以考虑折半3^(n/2)。前一半我们得到a,b,c,后一半我们得到x,y,z,我们要得到a+x=b+y=c+z。将式子变形为a-b=y-x和b-c=z-y,所以用map记录a-b和b-c,以及对应的最大的a和状态(三进制表示)。然后查找y-x和z-y是否存在,得到答案即可。

#include<cstdio>
#include<map>
#include<vector>
typedef long long ll;
using namespace std;
map < pair<int,int>, pair<int,int> > mp;
map < pair<int,int>, pair<int,int> > :: iterator it;
int ans=-97797977,n,a[30][4];
ll front,back;
vector <int> v;

int read()
{
    int ans=0,fu=1;
    char j=getchar();
    for (;(j<'0' || j>'9') && j!='-';j=getchar()) ;
    if (j=='-') j=getchar(),fu=-1;
    for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
    return ans*fu;
}

void dfs1(int x,int l,int m,int w,int f)
{
    if (x>n/2)
    {
    it = mp.find(make_pair(l-m,w-m));
    if (it!=mp.end())
        if(l>it->second.first)
        mp[make_pair(l-m,w-m)]=make_pair(l,f);
    else
        mp[make_pair(l-m,w-m)]=make_pair(l,f);
    return ;
    }
    dfs1(x+1,l+a[x][1],m+a[x][2],w,f*3+0);
    dfs1(x+1,l+a[x][1],m,w+a[x][3],f*3+1);
    dfs1(x+1,l,m+a[x][2],w+a[x][3],f*3+2);
}

void dfs2(int x,int l,int m,int w,int f)
{
    if (x>n)
    {
    it=mp.find(make_pair(m-l,m-w));
    if (it!=mp.end())
    {
        if (it->second.first+l>ans)
        {
        ans=it->second.first+l;
        front=it->second.second;
        back=f;
        }
    }
    return ;
    }
    dfs2(x+1,l+a[x][1],m+a[x][2],w,f*3+0);
    dfs2(x+1,l+a[x][1],m,w+a[x][3],f*3+1);
    dfs2(x+1,l,m+a[x][2],w+a[x][3],f*3+2);
}

void print(int x)
{
    if (!x) printf("LM\n");
    else if (x==1) printf("LW\n");
    else printf("MW\n");
}

int main()
{
    n=read();
    for (int i=1;i<=n;i++)
    {
    a[i][1]=read();
    a[i][2]=read();
    a[i][3]=read();
    }
    dfs1(1,0,0,0,0);
    dfs2(n/2+1,0,0,0,0);
    if (ans>-97797977)
    {
    for (int i=n-n/2;i>=1;i--)
    {
        v.push_back(back%3);
        back/=3;
    }
    for (int i=n/2;i>=1;i--)
    {
        v.push_back(front%3);
        front/=3;
    }
    for (int i=v.size()-1;i>=0;i--)
        print(v[i]);
    }
    else printf("Impossible");
    return 0;
}

[codeforces] 585D Lizard Era: Beginning || 双向dfs

标签:make   long   iterator   oid   双向   span   har   表示   vector   

原文地址:http://www.cnblogs.com/mrha/p/8018222.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!