2019西安邀请赛 D. Miku and Generals

这绝对是我近期写过最沙雕的一份代码。。

题目链接:https://nanti.jisuanke.com/t/39271

题意不讲

重现的时候三分钟给队友口胡了个思路就有事去找老师了,结果队友不信我QAQ,自己晚上回来瞎鸡儿写就过了?

思路:随便找个结点开始搜着去,按dfs树,奇数层加在一起当一个物品,偶数层加在一起当一个物品,其实就是形成两个互相独立的点集。完了以后判断价值,价值为0的直接扔掉即可,加没加跟他没关系。如果两个物品价值都不为0,就代表着我们两个玩家一定要一人选一个,不能一人选俩;如果两个物品一个价值为0,一个不为0,那这个不为0的物品我们哪个玩家选都行(永远不会冲突)。

知道这个就好办了:对于价值同时不为0的情况,看作一组,分出来讨论。

那么我们最后确定结果的时候,我们背包必须装有总组数的物品,也就是分组的物品必须得每组拿了一个,其他的随便放即可。

代码如下(有错的话希望大牛指点出来):

include
using namespace std;
typedef long long ll;
struct cc
{

int val,id;
};

bool vis[205];
int dp1[100005];
int dp2[100005];
int dp3[100005];
int a[205];

vectore[20005];
vectorq1;
vectorq2;
vectorq3;

int dfs(int u,bool sym)
{

vis[u]=true;
if(sym) q1.push_back(u);
else q2.push_back(u);
for(int i=0;i=q3[i].val;j--)
            {
                dp2[j]=dp1[j-q3[i].val]+1; // +1是代表我们拿了一个组里的一个物品
                if(dp2[j]>dp1[j]&&dp2[j]==num) dp1[j]=dp2[j]; // 然后更新结果数组
            }
            for(j=sum;j>=q3[i+1].val;j--)
            {
                dp3[j]=dp1[j-q3[i+1].val]+1; // +1是代表我们拿了一个组里的一个物品
                if(dp3[j]>dp1[j]&&dp3[j]==num) dp1[j]=dp3[j]; // 然后更新结果数组
            }
            i++; 
        }
        else
        {
            for(j=sum;j>=q3[i].val;j--)  //前后俩物品不同组,代表当前物品随便放即可
            {
                dp2[j]=dp1[j-q3[i].val];
                if(dp2[j]>dp1[j]&&dp2[j]==num) dp1[j]=dp2[j];// 然后更新结果数组
            }
        }
    }
    for(;sum>=0;sum--)  
    {
        if(dp1[sum]==tot)
        {
            ans=sum;
            break;
        }
    }
    printf("%d\n",(u-ans)*100);
}
return 0;
}

 

你可能感兴趣的:(dp)