编程练习赛80 卡片序列

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

一张卡片可以被表示成这种形式 [color1 | value | color2],也可以通过翻转操作变成[color2 | value | color1]。两张卡片能够连接,当且仅当左边卡片右边的颜色和右边卡片左边的颜色相同。

现在你有n张这样的卡片,你可以通过翻转和连接操作将其中一部分卡片串成一串,现在你需要求出你能够串成的卡片序列中,value总值最大的是多少。

输入

第一行一个数n

接下来n行,每行三个数,表示color1、value、color2

对于30%的数据,n ≤ 5

对于60%的数据,n ≤ 40

对于100%的数据,1 ≤ n ≤ 1000, 0 ≤ value ≤ 100000, 1 ≤ color ≤ 4

输出

输出一个数,表示答案

样例输入

6
3 70 4
2 26 3
4 39 4
2 77 1
2 88 1
4 43 2

样例输出

343

思路:将4种颜色看成4个顶点,值看成边的权重,建立一个无向图。顶点之间可能有多条边如果是奇数dfs时就全部加上,

偶数时留一条边从下一个顶点进行dfs(这条剩下的边下个顶就会遍历到)这点是关键,需要好好体会一下。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<algorithm>
#define LL long long
#define INF 1e9
using namespace std;
const int maxn=1e3+100;
int mp[5][5];
int c[5][5];
int Min[5][5];
int ans=0;
int vis[5][5];
void dfs(int id,int sum)
{
    sum+=mp[id][id];
    int gg=mp[id][id];
    //cout<<gg<<endl;
    mp[id][id]=0;
    for(int i=1;i<=4;i++)
    {
       if(i!=id&&c[id][i])
       {
           int h=sum;
           h+=mp[id][i];
           int v=mp[id][i];
           int cnt=c[id][i];
           mp[id][i]=0;
           mp[i][id]=0;
           if(c[id][i]%2==0)
           {
               h-=Min[id][i];
           }
           c[id][i]=(c[id][i]+1)%2;
           c[i][id]=c[id][i];
           mp[id][i]=Min[id][i];
           mp[i][id]=Min[id][i];
           dfs(i,h);
           mp[id][i]=v;
           mp[i][id]=v;
           c[i][id]=cnt;
           c[id][i]=cnt;
       }
    }
    mp[id][id]=gg;
    ans=max(ans,sum);
    //cout<<ans<<endl;
    return ;
}
int main()
{
    int n;
    scanf("%d",&n);
    memset(mp,0,sizeof(mp));
    memset(c,0,sizeof(c));
    for(int i=1;i<=4;i++)
    {
        for(int j=1;j<=4;j++)
        {
            Min[i][j]=INF;
        }
    }
    for(int i=1;i<=n;i++)
    {
        int x,value,y;
        scanf("%d%d%d",&x,&value,&y);
        if(y==x)
        {
            mp[x][y]+=value;
            continue;
        }
        mp[x][y]+=value;
        mp[y][x]+=value;
        Min[x][y]=min(Min[x][y],value);
        Min[y][x]=min(Min[y][x],value);
        c[x][y]++;
        c[y][x]++;
    }
    for(int i=1;i<=4;i++)
    {
        dfs(i,0);
    }
    printf("%d\n",ans);
    return 0;
}

感悟:转换成图,和偶数边的处理解题的关键,我也是看了大佬的才会,菜鸡有天也会变大佬。

猜你喜欢

转载自blog.csdn.net/wxl7777/article/details/83386242