zoukankan      html  css  js  c++  java
  • Dima and Salad 题解(01背包变形)

    题目链接

    题目大意

    给你n个物品,每个物品有两个值一个为a,一个为b

    要你拿任意的物品使得\(\sum a/ \sum b=k ,且max(\sum a)\)

    \(1<=n<=100\; 1<=k=10\; 1<=a[i],b[i]<=100\)

    题目思路

    一个显然易见的思路设\(dp[i][j]\)为是否有\(\sum a=i\; \sum b=j\)

    然后最后复杂度为\(O(1e10)\) 显然不行

    所以考虑化简

    把这个问题转化为每个物品重量为\(a[i]-k*b[i]\) 价值为\(a[i]\)

    转化为变为01背包

    然后由于有负数,所以把背包的初始体积平移一下即可

    代码

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define debug cout<<"I AM HERE"<<endl;
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
    const int eps=1e-3;
    int n,k;
    int a[110],b[110];
    int dp[110][maxn];
    signed main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&b[i]);
        }
        int mid=1e5;
        for(int i=0;i<=n;i++){ //初始化为负无穷
            for(int j=0;j<=2e5;j++){
                dp[i][j]=-inf;
            }
        }
        dp[0][mid]=0;
        for(int i=1;i<=n;i++){
            int w=a[i]-k*b[i];
            int v=a[i];
            for(int j=1;j<=2e5;j++){
                if(j>=w&&dp[i-1][j-w]!=-inf){
                    dp[i][j-w]=max(dp[i][j-w],dp[i-1][j-w]); //不选
                    dp[i][j]=max(dp[i][j],dp[i-1][j-w]+v); //选
                }
            }
        }
        printf("%d\n",dp[n][mid]<=0?-1:dp[n][mid]);
        return 0;
    }
    
    
    不摆烂了,写题
  • 相关阅读:
    线段树(已修改+补题
    畅通工程
    线段树
    charles
    flash
    mysql node pool
    node简单操作mysql的类
    小于任意数字的随机数
    文件系统的移植
    驱动
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14394019.html
Copyright © 2011-2022 走看看