2021牛客寒假算法基础集训营5
D 石子游戏
差分数组
#include <bits/stdc++.h>
//#pragma GCC optimize(2)
#define int long long
using namespace std;
const int mod = 998244353;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int inf = 1e18;
//const int mod = 1e9 + 7;
const int maxn = 1e5 + 10;
const int N = 1e7 + 10000;
int a[maxn];
void solve() {
int n,k;
cin>>n>>k;
for (int i = 1; i <=n; ++i) {
cin>>a[i];
}
for (int i = n; i >0; --i) {
a[i]-=a[i-1];
}
int ans=0;
for (int i = n; i >1; --i) {
if (i>k&&a[i]>0) ans+=a[i],a[i-k]+=a[i],a[i]=0;
}
int f=1;
for (int i = 2; i <=n; ++i) {
if (a[i]<0&&(i%k==(n+1)%k)){
ans-=(n+1-i)/k*a[i],a[i]=0;
}
f&=!a[i];
}
cout<<(f?ans:-1)<<"\n";
}
signed main() {
// ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
cin >> _;
while (_--) {
solve();
}
return 0;
}
G 模仿游戏
#include <bits/stdc++.h>
//#pragma GCC optimize(2)
#define int long long
using namespace std;
const int mod = 998244353;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int inf = 1e18;
//const int mod = 1e9 + 7;
const int maxn = 2e5 + 10;
const int N = 1e7 + 10000;
vector<int > vec[maxn];
int vis[maxn];
void solve() {
memset(vis,0,sizeof(vis));
for (int i = 0; i <maxn; ++i) vec[i].clear();
int n;
cin>>n;
for (int i = 1; i <=n; ++i) {
int t,x;
cin>>t>>x;
vec[t].push_back(x);
}
int t1=0,t2=0;
for (int i = 1; i <maxn; ++i) {
for (int j = 0; j < vec[i].size(); ++j) {
int u=vec[i][j];
if (vis[u]==0){
vis[u]=i;
t1=max(t1+1,i);
} else{
if (vis[u]==i){
t2=max(t2+1,i+1);
} else t2=max(t2+1,i);
}
}
if (t1<i&&t2>i){
t1=i;
t2--;
}
}
cout<<max(t1,t2)<<"\n";
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
cin >> _;
while (_--) {
solve();
}
return 0;
}
E 树上博弈
dfs/状压
#include <bits/stdc++.h>
//#pragma GCC optimize(2)
#define int long long
using namespace std;
const int mod = 998244353;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int inf = 1e18;
//const int mod = 1e9 + 7;
const int maxn = 2e5 + 10;
const int N = 1e7 + 10000;
int dp[(1<<20)+15];
int a[50];
vector<int > edge[50];
int vis[(1<<20)+15];
int deg[50];
int n;
void judge(int p){
if (vis[p]) return;
vis[p]=1;
for (int i = 0; i < n; ++i) {
if ((((1<<i)&p)==0)&°[i]<=1){
for (int j = 0; j < edge[i].size(); ++j) {
deg[edge[i][j]]--;
}
judge(p^(1<<i));
for (int j = 0; j < edge[i].size(); ++j) {
deg[edge[i][j]]++;
}
}
}
}
void dfs(int p,int step){
if (p==(1<<n)-1){
dp[p]=0;
return;
}
if (!vis[p]) return;
if (dp[p]!=inf) return;
int ans=inf;
for (int i = 0; i < n; ++i) {
if ((p&(1<<i))==0){
dfs(p^(1<<i),step-1);
if (dp[p^(1<<i)]==inf) continue;
if (ans==inf) {
if (step%2)ans=dp[p^(1<<i)]-a[i];
else ans=dp[p^(1<<i)]+a[i];
} else{
if (step%2) ans=min(ans,dp[p^(1<<i)]-a[i]);
else ans=max(ans,dp[p^(1<<i)]+a[i]);
}
}
}
dp[p]=ans;
}
void solve() {
cin>>n;
for (int i = 0; i <=(1<<n)+3; ++i) {
dp[i]=inf;
vis[i]=0;
}
memset(deg,0,sizeof(deg));
for (int i = 0; i <=n; ++i) edge[i].clear();
for (int i = 0; i <n; ++i) cin>>a[i];
for (int i = 1; i < n ; ++i) {
int u,v;
cin>>u>>v;
u--;
v--;
edge[u].push_back(v);
edge[v].push_back(u);
deg[u]++;
deg[v]++;
}
judge(0);
dfs(0,0);
cout<<dp[0]<<"\n";
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
cin >> _;
while (_--) {
solve();
}
return 0;
}