牛客 粉刷匠(dp)
有些题目可以进行二维dp,当然这题用四维也可以做。
我们先做每一行,f[][][],表示第i个用j次,涂前k个的最大值。
做完后,可以把它看作分组背包问题,每个木板都是一个物品,再跑一边dp即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int N=3e5+10; int f[55][2510][55]; int g[55][2510]; string s[N]; int w[55][55][55]; int main(){ int n,m,t; cin>>n>>m>>t; int i,j,k; for(i=1;i<=n;i++){ cin>>s[i]; s[i]=" "+s[i]; for(j=1;j<=m;j++){ int cnt1=0,cnt2=0; for(k=j;k>=1;k--){ if(s[i][k]=='1') cnt1++; else cnt2++; w[i][k][j]=max(cnt1,cnt2); } } } for(k=1;k<=n;k++){ for(i=1;i<=m;i++){ for(j=1;j<=m;j++){ for(int l=0;l<j;l++){ f[k][i][j]=max(f[k][i][j],f[k][i-1][l]+w[k][l+1][j]); } } } } int ans=0; for(i=1;i<=n;i++){ for(j=1;j<=t;j++){ for(k=0;k<=min(j,m);k++) g[i][j]=max(g[i][j],g[i-1][j-k]+f[i][k][m]); ans=max(g[i][j],ans); } } cout<<ans<<endl; }
没有人不辛苦,只有人不喊疼