zoukankan      html  css  js  c++  java
  • HDU 1171 Big Event in HDU

    HDU_1171

        这个题目可以用生成函数的思路去做,也可以用多重背包的思路去做,而且用多重背包的思路做时可以参考《背包九讲》里面的二进制优化多重背包问题那一块,这样做效率更高。

        另外多重背包问题用单调队列优化之后还可以达到O(VN)的效果,我暂时还没有学,所以就只写了这个二进制优化的版本。

    //生成函数
    #include<stdio.h>
    #include<string.h>
    #define MAXD 60
    #define MAXM 130000
    int N, S, M, value[MAXD], num[MAXD], wa[MAXM], wb[MAXM], *a, *b;
    void init()
    {
    int i, j, k;
    S = 0;
    for(i = 1; i <= N; i ++)
    {
    scanf("%d%d", &value[i], &num[i]);
    S += value[i] * num[i];
    }
    M = S / 2;
    }
    void solve()
    {
    int i, j, k, *t;
    a = wa, b = wb;
    memset(b, 0, sizeof(b[0]) * (M + 1));
    b[0] = 1;
    for(i = 1; i <= N; i ++)
    {
    memset(a, 0, sizeof(a[0]) * (M + 1));
    for(j = 0; j <= num[i]; j ++)
    for(k = 0; k + value[i] * j <= M; k ++)
    a[k + value[i] * j] += b[k];
    t = a, a = b, b = t;
    }
    for(i = M; i > 0; i --)
    if(b[i])
    break;
    printf("%d %d\n", S - i, i );
    }
    int main()
    {
    for(;;)
    {
    scanf("%d", &N);
    if(N < 0)
    break;
    init();
    solve();
    }
    return 0;
    }
    //多重背包
    #include<stdio.h>
    #include<string.h>
    #define MAXD 500
    #define MAXM 130000
    int N, M, S, X, value[MAXD], wa[MAXM], wb[MAXM], *a, *b, elem[] = {1, 2, 4, 8, 16, 32, 64, 128};
    void init()
    {
    int i, j, k, v, n;
    X = S = 0;
    for(i = 0; i < N; i ++)
    {
    scanf("%d%d", &v, &n);
    S += v * n;
    for(j = 0; n - elem[j + 1] + 1 > 0; j ++)
    value[X ++] = elem[j] * v;
    value[X ++] = (n - elem[j] + 1) * v;
    }
    M = S / 2;
    }
    void solve()
    {
    int i, j, k, *t;
    a = wa, b = wa;
    memset(b, 0, sizeof(b[0]) * (M + 1));
    for(i = 0; i < X; i ++)
    {
    for(j = 0; j <= M; j ++)
    {
    a[j] = b[j];
    if(j >= value[i] && b[j - value[i]] + value[i] > a[j])
    a[j] = b[j - value[i]] + value[i];
    }
    t = a, a = b, b = t;
    }
    printf("%d %d\n", S - b[M], b[M]);
    }
    int main()
    {
    for(;;)
    {
    scanf("%d", &N);
    if(N < 0)
    break;
    init();
    solve();
    }
    return 0;
    }



  • 相关阅读:
    PHP 如何阻止用户上传成人照片或者裸照
    centos 从php5.1升级php到5.3的方法
    用jQuery实现鼠标移动切换图片动画
    利用表格实现大图轮播
    css导行下拉动画
    java script 基本函数
    java script 数组去重两种方法
    java script两个列表之间移动数据
    JavaScript做个时间表 Date()
    JS For 循环详解;棋盘放粮食 64;冒泡排序实例
  • 原文地址:https://www.cnblogs.com/staginner/p/2382003.html
Copyright © 2011-2022 走看看