阿里2020-07-17提前批二道AC代码(二)。
题目忘了。
后面看有没有人记得,补。
#include <bits/stdc++.h>
#include "iostream"
using namespace std;
const int N = 1010;
int n, m, c0, d0;
int a, b, c, d;
struct Node {
int v, w;
};
int dp[1010][1010];
//int dp[N];
int main() {
vector<Node> ns;
cin>>n>>m>>c0>>d0;
for (int i = 0; i < m; ++i) {
cin>>a>>b>>c>>d;
int cnt = a / b, k = 1;
//问题转化为01背包
//多重背包转化01背包第二层次优化做法(第一层次 不优化,遍历全部k,第二层次,通过1 2 4 8这种因式分解,第三层次 单调队列)
//任何正整数数都可以 通过 1 2 4 8 等加上余数 表示。优化解空间。
while (cnt) {
if (cnt >= k) {
ns.push_back(Node{k * c, k * d});
cnt -= k;
k *= 2;
} else {
ns.push_back(Node{cnt * c, cnt * d});
cnt = 0;
}
}
}
// for (int i = 0; i < ns.size() + 1; ++i) {
// if (i == ns.size()) {
// for (int j = c0; j <= n; ++j)
// dp[j] = max(dp[j], dp[j - c0] + d0);
// } else {
// for (int j = n; j >= ns[i].v; --j)
// dp[j] = max(dp[j], dp[j - ns[i].v] + ns[i].w);
// }
// }
// printf("%d\n", dp[n]);
//
//填充 0,0 做为01背包初始化
ns.insert(ns.begin(),{0,0});
for(int i = 1;i<ns.size()+1;i++){
//遍历全部ns中结点,属于01背包问题
if(i!=ns.size()){
for(int j = 0;j<=n;j++){
if(j<ns[i].v){
dp[i][j]=dp[i-1][j];
}else{
dp[i][j] = max(dp[i-1][j],dp[i-1][j-ns[i].v]+ns[i].w);
}
}
} else{
//当ns中结点都遍历完了,开始通过剩余物品的更新dp,此时转化为完全背包(只要体积够,可无限使用)。
for(int j = 0 ; j<=n ;j++){
dp[i][j] = dp[i-1][j];
if(c0<=j){
dp[i][j]=max(dp[i][j],dp[i][j-c0]+d0);
}
}
}
}
cout<<dp[ns.size()][n];
return 0;
} #阿里巴巴#
查看16道真题和解析
阿里巴巴公司氛围 652人发布