Educational #39D

预处理+分组背包

预处理出每天逃x节课的最大收益,然后每天为一组,最多选一个,分组背包计算

分组背包的时候遇到一点小坑,就是状态转移方程 dp[i][j] = max(dp[i][j], dp[i-1][j-c[k]]+v[k]) 写成 dp[i][j] = max(dp[i-1][j], dp[i-1][j-c[k]]+v[k]),后者是错误的, 注意到,前者是在第i组每一次挑选出一个物品,然后与第i天挑出的其他物品比较选择较优的答案, 而后者是第i天挑出一个物品,每次与前i-1天的比较,也就是说没有在第i天里挑出最优的答案,而是选择了一个相对于前i-1天更优的答案(其实一定会比前i-1天更优,因为多拿了一件物品,这是无意义的选择)

#include "iostream"
#include "iomanip"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#pragma comment(linker, "/STACK:102400000,102400000")
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a,x) memset(a,x,sizeof(a))
#define step(x) fixed<< setprecision(x)<<
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define ll long long
#define endl ("\n")
#define ft first
#define sd second
#define lrt (rt<<1)
#define rrt (rt<<1|1)
using namespace std;
const ll mod=1e9+7;
const ll INF = 1e18+1LL;
const int inf = 1e9+1e8;
const double PI=acos(-1.0);
const int N=1e5+100;

int n, m, k, a[505][505], c[505][505], sum[505], dp[505][505], ans;
int main() {
    scanf("%d %d %d", &n, &m, &k);
    for(int i=1; i<=n; ++i) {
        int al = 505, br = -1;
        for(int j=1; j<=m; ++j) {
            char c; cin>>c;
            a[i][j] = c-'0';
            sum[j] = sum[j-1] + a[i][j];
            if(a[i][j] == 1) {
                al = min(al, j), br = max(br, j);
            }
        }
        int t = br-al+1;
        if(al == 505 && br == -1) t=0;
        ans += t;
        c[i][sum[m]] = t;
        for(int l=1; l<=m; ++l) {
            if(!a[i][l]) continue;
            for(int r=l; r<=m; ++r) {
                if(!a[i][r]) continue;
                int x = sum[m] - (sum[r]-sum[l-1]);
                c[i][x] = max(c[i][x], t - (r-l+1));
            }
        }
    }
    for(ill a, b;

void step1() {
    if(a==0 || b==0) return;
    else if(a >= 2*b) {
        a %= 2*b;
        step1();
    }
    else if(b >= 2*a) {
         b %= 2*a;
        step1();
    }
}

int main() {
    scanf("%lld %lld", &a, &b);
    step1();
    printf("%lld %lld\n", a, b);
    return 0;
}nt i=1; i<=n; ++i) {
        for(int j=0; j<=k; ++j) {
            for(int l=0; l<=j; ++l) {
                dp[i][j] = max(dp[i][j], dp[i-1][j-l]+c[i][l]);
            }
        }
    }
    printf("%d", ans-dp[n][k]);
    cout<<ans-dp[n][k]<<endl;
    return 0;
}

 

posted on 2018-03-20 20:40  lazzzy  阅读(101)  评论(0编辑  收藏  举报

导航