Codeforces Round #638 (Div. 2) E. Phoenix and Berries dp
Codeforces Round #638 (Div. 2) E. Phoenix and Berries dp
题意
有n个灌木丛,每个灌木丛有\(a_i\)个红色浆果,\(b_i\)个蓝色浆果。一个篮子可以装k个浆果,并且每个篮子只能承载要么是同一个灌木丛摘下来的浆果,要么是同一颜色的浆果,问最多装满多少个篮子(n<=500,k<=500)
分析
首先数据很DP,往DP靠一靠。最关键的是要发现每个灌木丛最多只能产出一个混色的篮子(因为假如你产生了多个混色篮子,那么他们可以经过互相交换,最后剩下一个混色的篮子),能想到这一步,这一题也就好做了。
要想知道这个混色篮子有几个红的几个蓝的,只要枚举就行了,那么组成完混色篮子后,同色的能产生多少个呢?我们只需要记录一下状态即可,可以只记录红的或者蓝的,另外一个可以O(1)算出来(DP常用的手段),也就是说用一维扫1--n个篮子,一维记录红的或者蓝的(我们这里选红的)的剩余数量,这里的数量一定是小于k的,因为如果大于k直接组成篮子加进dp值就行了。
所以我们设置状态为dp[i][j]前i个篮子剩下j个红的时候的最大篮子数量
我们设前i-1个的红蓝和为sum,此时红色的剩余数量为\(j+a[i]\),蓝色的剩余数量为\(sum-dp[i-1][j]*k-j+b[i]\)
所有当能组成混色蓝色时,我们设有红的z个,那么蓝的就有k-z个,转移为
\(dp[i][(j+a[i]-z)\%k]=max(dp[i][(j+a[i]-z)\%k],dp[i-1][j]+1+(j+a[i]-z)/k+(sum-j-k*(dp[i-1][j])-(k-z)+b[i])/k)\)
不组成混色篮子的时候转移为
\(dp[i][(j+a[i])\%k]=dp[i-1][j]+(j+a[i])/k+(sum-j-dp[i-1][j]*k+b[i])/k;\)
能和不能状态相同的时候取最大即可
复杂度\(O(nk^2)\)有点极限,不过1.25e8,2秒也差不多
ps:刚开始a[i],b[i]用的long long,cf的机器好像是32位的,直接卡掉了,改成了int就过了。。下次碰到这种情况可以考虑一下快读,偷懒fst就凉了
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define F first
#define S second
#define mkp make_pair
#define pii pair<int,int>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=5e3+4;
ll dp[maxn][maxn];
int a[maxn],b[maxn];
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]);
memset(dp,-1,sizeof(dp));
dp[0][0]=0;
ll sum=0;
for(int i=1;i<=n;i++){
for(int j=0;j<k;j++){
if(dp[i-1][j]==-1)continue;
dp[i][(j+a[i])%k]=dp[i-1][j]+(j+a[i])/k+(sum-j-dp[i-1][j]*k+b[i])/k;
for(int z=0;z<k;z++){
if(a[i]>=z&&b[i]>=(k-z))
dp[i][(j+a[i]-z)%k]=max(dp[i][(j+a[i]-z)%k],dp[i-1][j]+1+(j+a[i]-z)/k+(sum-j-k*(dp[i-1][j])-(k-z)+b[i])/k);
}
}
sum+=a[i]+b[i];
}
/*for(int i=1;i<=n;i++){
for(int j=0;j<k;j++){
cout<<dp[i][j]<<" ";
}
cout<<endl;
}*/
ll ans=0;
for(int i=0;i<k;i++)ans=max(ans,dp[n][i]);
printf("%lld\n",ans);
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!