2022.9.9 总结
A
问 \(n\) 个数 (\(\le 10^5\)),挑任意数,问有没有多种方法使和相等。
若没有和相等,我们构造极限数列为 \(1,2,4,8...\),每个都不同。
然而因为 \(a_i\le 10^5\) ,这样数列长度最多为 \(20\).
所以 \(n>20\),答案为有。剩下部分暴力。
B
\(A\) 和 \(B\) 在玩简单的取石子游戏。最初有 \(n\) 堆石子,每堆有 \(2\) 块。
\(A\) 和 \(B\) 轮流取石子(从 \(A\) 开始)。可以任选一堆拿走任意块。
此外,每 \(3\) 回合他们会添加一堆石子(含 \(2\) 块石子)。
暴力搜索找规律,若 \(n \mod 3=2\) 时 \(B\) 赢,否则 \(A\) 赢。
C
\(n\le 36\),选任意数使得异或和 \(\le m\),权值和最大。
剪枝可过。
code
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL N=40;
LL n,m,ans,a[N],b[N],sum[N];
void dfs(LL now,LL xs,LL s) {
if(now==n+1) {
if(xs<=m) ans=max(ans,s);
return;
}
if(s+sum[now]<=ans) return;
dfs(now+1,xs,s);
dfs(now+1,xs^a[now],s+b[now]);
}
signed main() {
scanf("%lld%lld",&n,&m);
for(LL i=1; i<=n; i++) scanf("%lld",&a[i]);
for(LL i=1; i<=n; i++) scanf("%lld",&b[i]);
for(LL i=n; i>=1; i--) sum[i]=max(sum[i+1],sum[i+1]+b[i]);
dfs(1,0,0);
printf("%lld",ans);
return 0;
}