【发布时间】:2019-06-05 12:14:42
【问题描述】:
我发现很难理解在 codeforces link 上解决此问题的两个具体实现。
我知道这类似于背包问题。但是,当我自己解决它时,我不知道该算法。我从自己对动态编程的理解中解决了这个问题。我的想法是将丝带的剩余长度视为下一个状态。这是我的代码
#include<iostream>
using namespace std;
int main(){
int n,res1=0,res2,x=0;
int a,b,c;
cin >> n >> a >> b >> c;
for(int i=0;i <= n/a; i++){
res2 = -20000;
for(int j=0; j <= (n-(a*i))/b; j++){
x = (n - (a*i) - (b*j));
res2=max(res2,(j + ((x % c) ? -10000 : x/c)));
}
res1=max(res1,i+res2);
}
cout << res1 << endl;
return 0;
实施 1:
1 #include <bits/stdc++.h>
2 using namespace std;
3 int main()
4 {
5 int f[4005],n,a,i,j;
6 fill(f+1,f+4005,-1e9);
7 cin>>n;
8 for(;cin>>a;)
9 for(i=a;i<=n;i++)
10 f[i]=max(f[i],f[i-a]+1);
11 cout<<f[n];
12 }
实施 2:
1 #include <bits/stdc++.h>
2 int n, a, b, c, ost;
3 std::bitset<4007> mog;
4 main()
5 {
6 std::cin>>n>>a>>b>>c;
7 mog[0]=1;
8 for (int i=1; i<=n; i++)
9 if ((mog=((mog<<a)|(mog<<b)|(mog<<c)))[n])
10 ost=i;
11 std::cout << ost;
12 }
虽然我理解解决背包问题的总体思路。我对实施 1 中的第 8、9、10 行如何实现这一点没有清楚的理解。具体而言,无论 a、b、c 的输入值如何,内部 for 循环都是针对接收到的相应值 a 对数组进行单次传递。
同样,我可以看到实现 2 中的第 8、9、10 行做了同样的事情。但我完全不知道这段代码是如何工作的。
请帮助我理解这一点。我觉得这两种解决方案有一些我没有看到的隐藏结构。提前致谢。
【问题讨论】:
-
第一个实现非常简单。与您的解决方案相比,它具有倒置的循环顺序:外循环通过
a,b,c,内循环设置数组中的所有元素。但我不明白 impl 2 是如何工作的。
标签: c++ knapsack-problem