题目链接
思路
每件装备只能用一次,如果把攻击序列建成点,就是装备和攻击顺序的匹配。
比如属性值是(3)和(5),那么这件装备要么在(3)位置要么在(5)位置被使用。
当然,按攻击顺序开始匹配,一旦匹配不成功,根据题意就必须中止。
每次都memset太慢了
代码
- 40pts:
/*
@ author:pyyyyyy
-----知识点------
暴力dfs
-----debug-------
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1000001;
int a[N],b[N],visit[N],ans,n;
void dfs(int now)
{
if(now>=n) return ;
if(now>ans) ans=now;
for(int i=1;i<=n;++i)
if(!visit[i]&&(a[i]==now+1||b[i]==now+1))
{
visit[i]=1;
dfs(now+1);
visit[i]=0;
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;++i)
cin>>a[i]>>b[i];
for(int i=1;i<=n;++i)
{
if(a[i]==1||b[i]==1)
{
visit[i]=1;
dfs(1);
visit[i]=0;
}
}
cout<<ans;
return 0;
}
- 100pts:
/*
@ author:pyyyyyy
-----知识点------
二分图最大匹配,把每个武器和他的属性连起来求最大匹配
-----debug-------
memset导致tle,可以用时间戳优化
*/
#include<bits/stdc++.h>
#include<stack>
#define MAXN 1010005
using namespace std;
vector<int> G[10005];
int visit[MAXN];
int v[MAXN];
int maxn;
int n;
stack<int> q;
int match(int u)
{
for(int i=0;i<G[u].size();++i)
{
int to=G[u][i];
if(visit[to]) continue;
visit[to]=1;
q.push(to);
if(!v[to]||match(v[to]))
{
v[to]=u;
return 1;
}
}
return 0;
}
void work()
{
memset(v,0,sizeof(v));
memset(visit,0,sizeof(visit));
int sum=0;
for(int i=1;i<=maxn;++i)
{
if(match(i)) sum++;
else break;
while(!q.empty()){
visit[q.top()]=0;
q.pop();
}
}
cout<<sum;
}
int main()
{
cin>>n;
maxn=0;
for(int i=1;i<=n;++i)
{
int u,v;
scanf("%d%d",&u,&v);
maxn=max(maxn,u),maxn=max(maxn,v);
G[u].push_back(i+10000),G[v].push_back(i+10000);
}
work();
return 0;
}