1 solutions

  • 3
    @ 2025-5-7 14:02:09

    多重背包基本逻辑:管你有一种物品有几个,全部拆成一个一个的看做单独的物品再遍历,也就是在遍历物体的循环里再套一个遍历物品个数的循环

    Cool! TLE!

    思路:用二进制差分把每一个物体的个数弄成2的k次幂,省了线性遍历的时间复杂度

    #include<iostream>
    using namespace std;
    int a,b,c,n,W,v[11415400],w[11451400],dp[191918100],cnt;
    int main(){
    	cin>>n>>W;
    	for(int i=1;i<=n;i++){
    		cin>>a>>b>>c;//输入每一个的价值,重量,个数 
    		for(int j=1;j<=c;j*=2){//二进制差分个数 
    			v[++cnt]=j*a;//直接把差出来的看作以一个新的个体,计算价值和重量 
    			w[cnt]=j*b;
    			c-=j;//减去差出去的数 
    		}
    		if(c!=0){//如果差完还有剩下的 
    			v[++cnt]=c*a;//一样直接看作个体,计算价值和重量  
    			w[cnt]=c*b;
    		}
    	}
    	for(int i=1;i<=cnt;i++){//01背包 
    		for(int j=W;j>=w[i];j--){
    			dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    		}
    	}
    	cout<<dp[W];
    	return 0;
    }
    

    如果还有不懂的去问n.cn,我有很多关于二进制查分的问题都是这样解决的

    (问我也不是不行

    • @ 2025-5-7 16:20:11

      善良

    • @ 2025-5-7 16:21:25

      好题解点了

    • @ 2025-5-7 16:49:40

      欸↑你说得对

    • @ 2025-5-7 16:50:42

      但是不二进制拆分优化也能AC

      🤓👆

      #include <bits/stdc++.h>
      using namespace std;
      const int N = 1e5 + 10;
      
      int n, m, money[N], heavy[N], num[N], dp[N];
      
      int main()
      {
      	cin >> n >> m;
      	for (int i = 1; i <= n; i++)
      		cin >> money[i] >> heavy[i] >> num[i];
      	
      	for (int i = 1; i <= n; i++)
      		for (int j = m; j >= heavy[i]; j--)
      			for (int k = 1; k <= num[i] and k * heavy[i] <= j; k++)
      				dp[j] = max(dp[j], dp[j - k * heavy[i]] + k * money[i]);
      	
      	cout << dp[m];
      	
      	return 0;
      }
      
    • @ 2025-5-7 16:52:02

      纯暴力也能A

      🤔

    • @ 2025-5-7 16:52:20

      @

    • @ 2025-5-7 22:11:12

      为啥叫二进制差分,这个跟差分有关系吗?这个题解区好,有两种解法时间复杂度讨论。

  • 1

Information

ID
749
Time
1000ms
Memory
125MiB
Difficulty
4
Tags
# Submissions
67
Accepted
15
Uploaded By