Codeforces Round #638 (Div. 2) E思维,,dp
题:
题意:给定n组,每组ai个红果,bi个白果。还给定整数k,代表组成同一盆要达成的数目,同时组成同一盆的水果要么是来自同一组,要么就是有相同颜色,问最大能组成多少盆
分析:初步地,我们可以只是按照颜色来分组,那么答案就是suma/k+sumb/k,那么就剩下不足k个的红果和不足k个的白果,这时我们发现,只要再从剩下的中凑出一组是来自同一组的,那么答案就会加一,而这种方法是最优的。那么我们就想办法让其他组分配合理而让某一组留下尽可能多的白果和红果(因为要让至少有suma/a+sumb/k盆)
考虑n<=500,那么我们可以枚举o(n^3)要保证至少盆的情况下,我们只能k个k个地加进去,而转移就是暴力地枚举【(1~k-1)+(k-1~1)】
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int M=5e2+3; int dp1[M][M],dp2[M][M]; int a[M],b[M]; int main(){ ios::sync_with_stdio(false); cin.tie(0); ll suma=0,sumb=0; int n,k; cin>>n>>k; for(int i=1;i<=n;i++) cin>>a[i]>>b[i],suma+=a[i],sumb+=b[i]; ll yua=suma%k,yub=sumb%k; if(yua+yub<k){ return cout<<suma/k+sumb/k,0; } dp1[k][0]=dp1[0][k]=1; for(int i=1;i<=n;i++){ for(int j=0;j<=k;j++) for(int p=0;p<=k;p++) dp2[i][j]=0; for(int j=0;j<=k;j++) dp2[j][k-j]=dp1[j][k-j]; for(int l=1;l<k;l++){ int r=k-l; if(l<=a[i]&&r<=b[i]){ // cout<<"!!"<<l<<' '<<r<<endl; for(int j=0;j<=k;j++){ dp2[(j+r)%k][(k-j+l)%k]|=dp1[j][k-j];/// } } } for(int j=0;j<=k;j++) dp1[j][k-j]=dp2[j][k-j]; } ll sign=0; for(int i=1;i<=yua;i++){ if(k-i<=yub&&dp2[k-i][i]) sign=1; } ///cout<<suma/k+sumb/k<<endl; return 0; }