A题
题意:r个红豆和b个绿豆,要求跟他们分组,每组至少有1个红豆和1个绿豆,且红豆的绿豆的个数相差不能超过d
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll t,a,b,c; int main() { std::ios::sync_with_stdio(false); cin>>t; while(t--) { cin>>a>>b>>c; if(min(a,b) * (c + 1) >= max(a,b)) cout<<"YES\n"; else cout<<"NO\n"; } return 0; }
B题
题意:问能否花费k从(1,1)移动到(n,m)
(x,y)花费y到达(x+1,y),花费x到达(x,y+1)
解:暴力可知所有到(n,m)的花费都相同,为nm-1
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; int t,a,b,c,s; void dfs(int x,int y) { if(x == a && y == b) { cout<<s<<endl; return; } if(x + 1 <= a) { s += y; dfs(x + 1,y); s -= y; } if(y + 1 <= b) { s += x; dfs(x,y + 1); s -= x; } } int main() { std::ios::sync_with_stdio(false); cin>>t; while(t--) { cin>>a>>b>>c; if(c != (a * b - 1)) cout<<"NO\n"; else cout<<"YES\n"; //s = 0; //dfs(1,1); } return 0; }
C题
题意:每个学校有若干个学生,他们都有各自的代码能力ai,每个学校派出若干组,每组k个人,问所有学校能派出的人的代码能力之和最大是多少
#include<bits/stdc++.h> using namespace std; const int maxn = 2e5 + 10; typedef long long ll; ll n,t,a[maxn],s[maxn],x; vector<ll>v[maxn]; void solve() { cin>>n; for(int i = 1;i <= n; ++i) v[i].clear(),s[i] = 0; for(int i = 1;i <= n; ++i) cin>>a[i]; for(int i = 1;i <= n; ++i) { cin>>x; v[a[i]].push_back(x); } for(int i = 1;i <= n; ++i) { sort(v[i].begin(),v[i].end()); reverse(v[i].begin(),v[i].end()); int k = v[i].size(); for(int j = 1;j < k; ++j) v[i][j] += v[i][j - 1]; for(int j = 1;j <= k; ++j) ///枚举k s[j] += v[i][k - 1 - k % j];///k % j } for(int i = 1;i <= n; ++i) cout<<s[i]<<((i == n)?'\n':' '); } int main() { std::ios::sync_with_stdio(false); cin>>t; while(t--) solve(); return 0; }
D题
题意:给出a和b,要求翻转一次a的子串,使得∑(ai*bi)最大
解:DP求解
#include<bits/stdc++.h> using namespace std; const int maxn = 5e3 + 10; typedef long long ll; ll n,t,a[maxn],b[maxn],s[maxn],ans,f[maxn][maxn]; void solve() { cin>>n; ans = 0; for(int i = 1;i <= n; ++i) cin>>a[i]; for(int i = 1;i <= n; ++i) cin>>b[i]; for(int i = 1;i <= n; ++i) s[i] = s[i - 1] + a[i] * b[i]; for(int l = n;l >= 1; --l) for(int r = l;r <= n; ++r) { if(l == r) f[l][r] = a[l] * b[l]; else if(l + 1 == r) f[l][r] = a[l] * b[r] + a[r] * b[l]; else f[l][r] = f[l + 1][r - 1] + a[l] * b[r] + a[r] * b[l]; } for(int i = 1;i <= n; ++i) for(int j = i;j <= n; ++j) ans = max(ans,s[i - 1] + f[i][j] + s[n] - s[j]); cout<<ans<<endl; } int main() { std::ios::sync_with_stdio(false); t = 1; while(t--) solve(); return 0; }