有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],值是w[i]。 求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 进一步优化,由于有数量约束,可以先将v[i]/w[i]比值按由大到小的顺序排列, 如用此法,应该用结构体做数据结构,然后用qsort排序,此处用到了qsort排序的技巧 其实就是01背包 不过是加入了每件物品的数量 #include<iostream> #include<fstream> using namespace std; #define max(a,b)(a>b ? a:b) const int MAX = 100; int v[MAX]; int w[MAX]; int num[MAX]; int dp[MAX]; int Weight; int zeroOnePack(int n) { for(int i=1; i<=n; i++) { for(int j=Weight; j>=w[i]; j--) { dp[j] = max(dp[j], v[i] + dp[j-w[i]]); } } return dp[Weight]; } int completePack(int n) { for(int i=1; i<=n; i++) { for(int j=w[i]; j<=Weight; j++) { dp[j] = max(dp[j], v[i] + dp[j-w[i]]); } } return dp[Weight]; } int multiPack(int n) { memset(dp,0,sizeof(dp)); for(int i=1; i<=n; i++) { for(int j=w[i]; j<=Weight; j++) { if(num[i]*w[i]>Weight) completePack(n); else { int k = 1; while(k<num[i]) { zeroOnePack(n); num[i] -= k; k += k; } zeroOnePack(n); } } } return dp[Weight]; } int main() { ifstream cin("in.txt"); ofstream cout("out.txt"); int n; while(cin >> n >> Weight && n) { int i; for(i=1;i<=n;i++) cin >> num[i]; for(i=1;i<=n;i++) cin >> v[i]; for(i=1;i<=n;i++) cin >> w[i]; int ans = multiPack(n); cout << ans << endl; } return 0; }