• 超大背包问题


    有一类背包问题中背包的体积很大但是价值很小,这种背包中如果按照正常的思维来写的话很容易超内存,可以换种思维,dp[I]表示价值为I的价值用的最小空间;
    例题:



    Knapsack problem
    Crawling in process... Crawling failed  

    Description

    Given a set of n items, each with a weight w[i] and a value v[i], determine a way to choose the items into a knapsack so that the total weight is less than or equal to a given limit B and the total value is as large as possible. Find the maximum total value. (Note that each item can be only chosen once).

    Input

    The first line contains the integer T indicating to the number of test cases.

    For each test case, the first line contains the integers n and B.

    Following n lines provide the information of each item.

    The i-th line contains the weight w[i] and the value v[i] of the i-th item respectively.

    1 <= number of test cases <= 100

    1 <= n <= 500

    1 <= B, w[i] <= 1000000000

    1 <= v[1]+v[2]+...+v[n] <= 5000

    All the inputs are integers.

    Output

    For each test case, output the maximum value.

    Sample Input

      1
      5 15
    12 4
      2 2
    1 1
    4 10
    1 2

    Sample Output

      15
    解体思路:首先这个很清楚看出来是个01背包。但是这个背包容量特别大,同时物品的体积很大,总的价值却很少。寻常意义上dp[i]表示背包容量为i时的最大价值,
    那么我们把这个dp[]数组的含义改变一下,dp[i]表示装价值为i时所需的最小容量。
    感悟:唉,压线过得真持基;
    #include
    #include
    #include
    using namespace std;
    const int maxn = 550;
    const int INF = 0x3f3f3f3f;
    int w[maxn], v[maxn];
    int dp[5500];
    int main(){
        freopen("in.txt","r",stdin);
        int T, n, B;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&B);
            int V = 0;
            for(int i = 1; i <= n; i++){
                scanf("%d%d",&w[i],&v[i]);
                V += v[i];
            }
            memset(dp,INF,sizeof(dp));
            dp[0] = 0;
            for(int i = 1; i <= n; i++){
                for(int j = V; j >= v[i]; j--){
                    dp[j] = min(dp[j],dp[j-v[i]]+w[i]);
                 //   printf("%d ",dp[j]);
                }
            }
            int ans = 0;
            for(int i = V; i >= 0; i--){
                if(dp[i] <= B){
                    ans = i; break;
                }
            }
            printf("%d ",ans);
        }
        return 0;
    }

  • 相关阅读:
    ASP.NET 数据库访问通用工具
    [原]ASP.NET 数据库访问通用工具
    [转]序号的结构层次顺序
    序号的结构层次顺序
    百度地图显示多个标注点
    [原]百度地图显示多个标注点
    [原]网站跨站点脚本,Sql注入等攻击的处理
    网站跨站点脚本,Sql注入等攻击的处理
    angular学习笔记(十二)-控制器
    angular学习笔记(十一)-表达式
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/5781536.html
Copyright © 2020-2023  润新知