Codeforces 946D - Timetable

946D - Timetable

思路:

分组背包

每组物品最多选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;
}

 

posted @ 2018-03-07 16:15  Wisdom+.+  阅读(404)  评论(0编辑  收藏  举报