0
点赞
收藏
分享

微信扫一扫

Educational Codeforces Round 108 (Rated for Div. 2) A-D题解

yongxinz 2022-06-29 阅读 62

A.Red and Blue Beans

  • 解题思路
    此题要求我们分组,使得红豆和蓝豆的数量不得超过Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_#include,也就是说一个红豆最多可以和Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_c++_02个蓝豆组成一组,同理一个蓝豆也是一样的,所以我们只需要判断数量较小的那个豆能否最大的配凑使其组成一组,假设较小的为Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_#include_03,较大的为Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_c++_04,那么即是判断Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_#include_05Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_c++_04的关系了。若大于等于,说明完全可以配成符合要求的组,否则不行。
  • 代码
/**
*@filename:A_Red_and_Blue_Beans
*@author: pursuit

*@created: 2021-04-29 22:35
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;

ll t,r,b,d;
void solve(){
if(r<b)swap(r,b);
if(b+b*d>=r){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
int main(){
cin>>t;
while(t--){
cin>>r>>b>>d;
solve();
}
return 0;
}

B. The Cake Is a Lie

  • 解题思路
    这道题属实有点坑,只要动手去算,发现不管怎样出发,到达Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_#include_07的消耗是一个定值,我们判断这个定值和Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_c++_08是否相等即可。
  • 代码
/**
*@filename:B_The_Cake_Is_a_Lie
*@author: pursuit

*@created: 2021-04-29 22:42
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;

int t,n,m,k;
void solve(){
if(k==(m-1)+m*(n-1)){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
int main(){
cin>>t;
while(t--){
cin>>n>>m>>k;
solve();
}
return 0;
}

C. Berland Regional

  • 解题思路
    我们对每个学校枚举Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_c++_08Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_c++_08实际上就是它们的最大成员数,那么为了凑成Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_c++_08的倍数,我们需要除去余数即可。为了更高效的求和,我们可以利用前缀和。
  • 代码
/**
*@filename:C_Berland_Regional
*@author: pursuit

*@created: 2021-04-29 23:11
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 200000 + 5;
const int mod = 1e9+7;

int t,n;//n为大学数量和学生数量。
vector<ll> g[maxn];//存储。
ll ans[maxn],u[maxn];
void solve(){
for(int i=1;i<=n;i++){
sort(g[i].begin(),g[i].end(),greater<int>() );
}
//前缀和。
for(int i=1;i<=n;i++){
for(int j=1;j<g[i].size();j++){
g[i][j]+=g[i][j-1];//前缀和
}
}
//对每个学校枚举k,k即为它们的最大成员数。
for(int i=1;i<=n;i++){
int k=g[i].size();
for(int j=1;j<=k;j++){
ans[j]+=g[i][k-k%j-1];//除去余数。
}
}
for(int i=1;i<=n;i++){
cout<<ans[i];
i==n?cout<<endl:cout<<" ";
}
}
int main(){
cin>>t;
while(t--){
cin>>n;
int temp;
for(int i=1;i<=n;i++){
cin>>u[i];
g[i].clear();
ans[i]=0;
}
for(int i=1;i<=n;i++){
cin>>temp;
g[u[i]].push_back(temp);
}
solve();
}
return 0;
}

D. Maximum Sum of Products

  • 解题思路
    一道区间Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_c++_12问题,我们先定义状态:Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_#include_13即表示的是翻转区间Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_i++_14之后这段区间Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_i++_15的最大值。那么为了方便,我们每次递推翻转左右端点即可,故状态转移方程即为Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_c++_16 处理完之后,最后需要枚举一遍区间取最大值。需要注意的是,我们枚举左端点的时候要从大到小,因为右端点Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_#include_17会用到Educational Codeforces Round 108 (Rated for Div. 2) A-D题解_#include_18
  • 代码
/**
*@filename:D_Maximum_Sum_of_Products
*@author: pursuit

*@created: 2021-04-30 10:34
**/
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 5000 + 5;
const int mod = 1e9+7;

int n;
ll a[maxn],b[maxn],dp[maxn][maxn],s[maxn];//区间dp。dp[l][r]即表示的是翻转区间[l,r]之后这段区间ai*bi的最大值。
//则易知状态转移方程为d[i][j]=dp[i+1][j-1]+a[i]*b[j]+a[j]*b[i];
void solve(){
}
int main(){
cin>>n;
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 i=1;i<=n;i++){
dp[i][i]=a[i]*b[i];
}
//枚举左右端点。
for(int i=n-1;i>=1;i--){
for(int j=i+1;j<=n;j++){
//注意这里的i必须是从大到小,因为我们的j会用到i+1。
dp[i][j]=max(dp[i][j],dp[i+1][j-1]+a[i]*b[j]+a[j]*b[i]);
}
}
//所有状态更新完之后开始取max。
ll ans=s[n];
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
ans=max(ans,dp[i][j]+s[i-1]+s[n]-s[j]);
}
}
cout<<ans<<endl;
solve();
return 0;
}


举报

相关推荐

0 条评论