zoukankan      html  css  js  c++  java
  • 动态规划——初步

    练习题集

    Greedy Tino

    滚动数组

    #include <cstdio>
    #include <algorithm>
    
    const int INF = 1e9;
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    #endif
        int t;
        while (scanf("%d", &t) != EOF) {
            int caseid = 0;
            while (t--) {
                int n;
                scanf("%d", &n);
                int w[101] = {0};
                int cnt = 0;
                bool hasZero = false;
                for (int i = 1; i <= n; ++i) {
                    scanf("%d", &w[++cnt]);
                    if (w[cnt] == 0) {
                        cnt--;
                        hasZero = true;
                    }
                }
                n = cnt;
                int dp[2][4001];
                int offset = 2000;
                for (int i = 0; i < 4001; ++i) dp[0][i] = -INF;
                dp[0][offset] = 0;
                int *des = dp[0];
                int *src = dp[1];
                for (int i = 1; i <= n; ++i) {
                    std::swap(des, src);
                    for (int j = -2000; j <= 2000; ++j) {
                        int temp = -INF;
                        if (j + w[i] <= 2000 && src[j + offset + w[i]] != -INF) 
                            temp = src[j + offset + w[i]] + w[i];
                        if (j - w[i] >= -2000 && src[j + offset - w[i]] != -INF) 
                            temp = std::max(temp, src[j + offset - w[i]] + w[i]);
                        des[j + offset] = std::max(temp, src[j + offset]);
                    }
                }
                printf("Case %d: ", ++caseid);
                if (des[offset] == 0) puts(hasZero ? "0" : "-1");
                else printf("%d
    ", des[offset] / 2);
            }
        }
        return 0;
    }
    View Code

    Watch The Movie

    二维背包问题是指每件物品都具有两种不同的开销,选择这件物品必须同时承担这两种开销,在选择物品的时候必须保证两种开销都不会超过相应的背包容量,求选择物品可以得到最大的权重。设第i件物品所需的两种开销分别为v[i]和u[i],两种开销所对应的背包容量分别为V和U,物品的价值为w[i]。

    分析:相比经典的01背包问题,二维背包问题增加了一维开销,于是我们需要在状态上增加一维。设s[i][j][k]表示将前i件物品放入两种容量分别为j和k的背包时所能获得的最大权重,则状态转移方程为s[i][j][k]=max{s[i-1][j][k], s[i-1][j-v[i]][k-u[i]]+w[i]},递推边界为当i=0时s[i][j][k]=0。和01背包类似,状态的维数可以很容易地从三维降低到二维,具体实现见代码。

    #include <cstdio>
    #include <algorithm>
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    #endif
        int t;
        while (scanf("%d", &t) != EOF) {
            while (t--) {
                int n, m, l;
                int val[101];
                int lon[101];
                int dp[101][1001] = {0};
                scanf("%d%d%d", &n, &m, &l);
                for (int i = 1; i <= n; ++i) 
                    scanf("%d%d",&lon[i], &val[i]);
                for (int i = 1; i <= m; ++i) {
                    for (int j = 0; j <= l; ++j) 
                            dp[i][j] = -1e9;
                }
                for (int i = 1; i <= n; ++i) { 
                    for (int j = l; j >= lon[i]; --j) 
                        for (int k = m; k >= 1; --k) 
                            dp[k][j] = std::max(dp[k][j], dp[k - 1][j - lon[i]] + val[i]);
                }
                if (dp[m][l] > 0) 
                    printf("%d
    ", dp[m][l]);
                else 
                    puts("0");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    在 easyui中获取form表单中所有提交的数据 拼接到table列表中
    easyui中清空table列表中数据
    easyui中加载table列表数据 第一次有数据第二次没有数据问题
    jsp中将一个jsp引入另一个jsp指定位置
    maven项目修改名称后,打包名称和现在名称不一致
    动态sql
    日期转化类 ,日期格式处理
    easyui中权限分配和添加 前后端代码
    ubuntu14.04下播放器SMplayer的安装
    C++的 new 和 detele
  • 原文地址:https://www.cnblogs.com/fripside/p/3561120.html
Copyright © 2011-2022 走看看