思路:
分组背包
每组物品最多选1个
v[i]表示对于这天来说减掉i节课后最多能减少多少小时的在校时间
代码:
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define ll long long #define pb push_back #define mp make_pair #define pii pair<int,int> #define mem(a,b) memset(a,b,sizeof(a)) string s[555]; int dp[555],v[555],ones[555]; vector<pii>vc[555]; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n,m,k; cin>>n>>m>>k; for(int i=1;i<=n;i++){ cin>>s[i]; int cnt=0; for(int j=0;j<m;j++){ if(s[i][j]=='1')ones[cnt++]=j+1; } mem(v,0); v[cnt]=m; for(int j=0;j<cnt;j++){ for(int k=j;k<cnt;k++){ int len=cnt-(k-j+1); int value=m-(ones[k]-ones[j]+1); v[len]=max(v[len],value); } } for(int j=0;j<=k;j++){ if(v[j])vc[i].pb(mp(j,v[j])); } } for(int i=1;i<=n;i++){ for(int j=k;j>=0;j--){ for(int k=0;k<vc[i].size();k++){ if(j>=vc[i][k].fi)dp[j]=max(dp[j],dp[j-vc[i][k].fi]+vc[i][k].se); } } } cout<<n*m-dp[k]<<endl; return 0; }