游戏
题意
给定一个集合
共
每一轮有一个参数
先手希望最终
问两人都采取最优策略,最终的值是多少。
思路
在这之前,我一直都不知道博弈论的题怎么写暴力。
这道题其实就是爆搜即可。
对于每一步,我们都搜可能的两种状态,然后当前层如果是先手,接受较小的;后手,接受较大的。
如果哪个集合没有东西了,直接返回
一共 return
了,所以每一层都是
实际上,当
先手每一次都会使得集合大小减半,最后一定会变成
#include<iostream>
#include<vector>
using namespace std;
const int N=20010,M=30;
typedef long long ll;
const ll INF=1e18;
int n,m,cnt;
ll b[M];
ll dfs(vector<ll>&a,int d){
vector<ll>t1,t2;
++cnt;
// printf("node=%d,dep=%d\n",cnt,d);
ll s1=INF,s2=INF;
for(ll v:a)
if(v%b[d]==0)t1.push_back(v);
else t2.push_back(v);
// printf("div by %lld,s1=%lld\n",b[d],s1);
// for(ll v:t1)printf("%d ",v);
// puts("\nother");
// for(ll v:t2)printf("%d ",v);
// puts("\n\n\n");
if(t1.empty())s1=0;
if(t2.empty())s2=0;
if(d==m){
s1=s2=0;
for(ll v:t1)s1+=v;
for(ll v:t2)s2+=v;
return d&1?min(s1,s2):max(s1,s2);
}
if(s1==INF)s1=dfs(t1,d+1);
if(s2==INF)s2=dfs(t2,d+1);
return d&1?min(s1,s2):max(s1,s2);
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
if(m>28){
putchar('0');
return 0;
}
vector<ll>a(n);
for(ll &v:a)cin>>v;
for(int i=1;i<=m;++i)cin>>b[i];
cout<<dfs(a,1);
// dfs(a,1);
return 0;
}
本文作者:wscqwq
本文链接:https://www.cnblogs.com/wscqwq/p/17768069.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步