题目描述
选取和不超过 S 的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大。
得意忘形
此题太蒟蒻了 ,我10分钟写完!!
大脑停顿
感觉能用DP,但不知道为什么能用背包(题目说能用背包)
茅塞顿开
后来想了一下,这不就是一道01背包吗?
其中S代表背包容量,每个数的约数和代表价值,它本身代表重量。
接下来就是01背包的模板了!!!
状态转移:
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
出错
额······怎么30分?
#include<bits/stdc++.h>
using namespace std;
int w[10005],v[10005],dp[1005][1005];
int ppt(int oi){
int res=0;
for(int i=1;i<oi;i++){
if(oi%i==0){
res+=i;
}
}
return res;
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
w[i]=i;
v[i]=ppt(i);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j<w[i]){
dp[i][j]=dp[i-1][j];
}
else{
dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+v[i]);
}
}
}
int ma=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ma=max(dp[i][j],ma);
}
}
cout<<ma;
}
这样其实是一个完全背包。
代码奉上
#include<bits/stdc++.h>
using namespace std;
int w[10005],v[10005],dp[1005][1005];
int ppt(int oi){
int res=0;
for(int i=1;i<oi;i++){
if(oi%i==0){
res+=i;
}
}
return res;
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
w[i]=i;
v[i]=ppt(i);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j<w[i]){
dp[i][j]=dp[i-1][j];
}
else{
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
}
}
}
int ma=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ma=max(dp[i][j],ma);
}
}
cout<<ma;
}