P8800 [蓝桥杯 2022 国 B] 卡牌
做法:使用优先队列,只能拿到40分,可以二分最多可以形成多少套牌,时间复杂度Onlogn
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m;
int a[200005],b[200005];
bool check(ll mid){
ll sum=0;
for (int i = 1; i <=n ; ++i) {
if(a[i]+b[i]<mid){
return 0;
}
if(a[i]<mid){
sum+=mid-a[i];
}
}
return sum<=m;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
ll l=1e15,r=0;
for (int i = 1; i <=n ; ++i) {
cin>>a[i];
if(a[i]<l)
l=a[i];
}
for (int i = 1; i <=n ; ++i) {
cin>>b[i];
if(b[i]+a[i]>r)
r=b[i]+a[i];
}
ll mid;
ll ans;
while (l<r){
mid=(l+r+1)>>1;
if(check(mid)){
l=mid;
}
else
r=mid-1;
}
cout<<r;
}
P8808 [蓝桥杯 2022 国 C] 斐波那契数组
思路:
动态规划f[i][j][k]表示遇到i次店j次花有k斗酒的方案数,答案就是f[n][m-1][1],并且k的区域值范围是[1,m],然后更具题目描述转移方程即可,注意如果上一次遇到了店,当前的k一定是偶数。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod=1e9+7;
int dp[105][105][105],n,m;
int main(){
cin>>n>>m;
dp[0][0][2]=1;
for (int i = 0; i <=n ; ++i) {
for (int j = 0; j <m ; ++j) {
for (int k = 0; k <=m ; ++k) {
if(j>0)dp[i][j][k]=(dp[i][j-1][k+1]+dp[i][j][k])%mod;
if(i>0&&k%2==0){
dp[i][j][k]=(dp[i][j][k]+dp[i-1][j][k/2])%mod;
}
}
}
}
cout<<dp[n][m-1][1];
}