这道题我卡在1的约数是0上了。。。。
思路:
题目所描述的就是01背包的情况:有s个物品,物品的重量从1到s,价值也是从1到s。
无优化的方法就是建立一个二维dp数组,行下标表示可以选到几个物品,列下标表示背包的容量。
详细的01背包解析可以看这个:
无优化:
#include<iostream>
#include<vector>
using namespace std;
int get(int n) {
int sum = 1;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
sum += i;
}
}
return sum;
}
int main() {
int n;
cin >> n;
vector<int> val;
vector<int> size;
for (int i = 1; i <= n; i++) {
size.push_back(i);
}
val.push_back(0);//1的约数是0
for (int i = 2; i <= n; i++) {
val.push_back(get(i));
}
vector<vector<int>> dp(n + 1, vector<int>(n + 1));
for (int i = 1; i <= n; i++) {
dp[1][i] = val[0];
}
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j] = dp[i - 1][j];
if (size[i-1] <= j) {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - size[i-1]] + val[i-1]);
}
}
}
cout << dp[n][n];
return 0;
}
优化:
#include<iostream>
#include<vector>
using namespace std;
int get(int n) {
int sum = 1;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
sum += i;
}
}
return sum;
}
int main() {
int n;
cin >> n;
vector<int> val;
vector<int> dp(n + 1);
val.push_back(0);
val.push_back(0);
for (int i = 2; i <= n; i++) {
val.push_back(get(i));
}
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
dp[j] = max(dp[j], dp[j - i] + val[i]);
}
}
cout << dp[n];
return 0;
}