dp方法
#include<bits/stdc++.h>
using namespace std;
int wei[5]={ 0 , 2 , 3 , 4 , 5 };
int val[5]={ 0 , 3 , 4 , 5 , 6 };
int bagWei=8;
int dp[5][10]={0};
int item[5]={0};//表示第i个物品有没有被放进背包
void findWhat(int i,int j)
{
if(i>=0){
if(dp[i][j]==dp[i-1][j]){//没放i
item[i]=0;
findWhat(i-1,j);
}
else if(j-wei[i]>=0&&dp[i][j-wei[i]]+val[i]){
item[i]=1;
findWhat(i-1,j-wei[i]);
}
}
}
int main()
{
ios::sync_with_stdio(false);
for(int i=1;i<5;i++){//第i个物品
for(int j=1;j<=bagWei;j++){//背包现在容量
if(j>=wei[i]){
dp[i][j]=max(dp[i-1][j-wei[i]]+val[i],dp[i-1][j]);
}
else{
dp[i][j]=dp[i-1][j];
}
}
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 9; j++) {
cout << dp[i][j] << ' ';
}
cout << endl;
}
//回溯找到应该装进去的东西
findWhat(4,8);
for(int i=1;i<5;i++){
cout<<item[i]<<" ";
}
cout<<endl;
return 0;
}
洛谷
#include<bits/stdc++.h>
using namespace std;
int len[5]={0};
int homework[25]={0};
int a[25][2000]={0};
int total=0;
int main()
{
ios::sync_with_stdio(false);
for(int i=1;i<=4;i++){
cin>>len[i];
}
for(int i=1;i<=4;i++){
int oneSum=0;//每门科目的时间总和
for(int j=1;j<=len[i];j++){
cin>>homework[j];
oneSum+=homework[j];
}
int t1=0;
for(int j=1;j<=len[i];j++){
for(int k=0;k<=oneSum/2;k++){
if(k<homework[j]){
a[j][k]=a[j-1][k];
}
else{
a[j][k]=max(a[j-1][k],a[j-1][k-homework[j]]+homework[j]);
}
t1=max(a[j][k],t1);
}
}
total+=max(t1,oneSum-t1);
}
cout<<total<<endl;
return 0;
}
dfs方法
大致意思就是现在有不同级别的孔,也有不同级别的珠子,每种珠子都有放进去增值的上限,求怎么放这些珠子才能使现在拥有的价值最大。
#include<bits/stdc++.h>
#define MAXN 55
#define MAXS 305
#define MAXM 10005
using namespace std;
int n[MAXN];//孔的数量
int levNum[5]={0};//四个等级的孔的个数
int L[MAXM],p[MAXM],w[MAXM][MAXN];
int dp[MAXM][MAXS];
int m;
int DP()
{
memset(dp,0,sizeof(dp));
int ans=0;//最终装备里面放了toa个珠子的总价值
int sum=0;//现在有的孔的总数量
int tot=0;//放的珠子数量
//先从等级高的往下枚举
//因为等级为l的珠子能够装进l-4的孔里面,此时的l-4的孔都有了
for(int l=4;l>=1;l--){
sum+=levNum[l];
for(int i=1;i<=m;i++){//种类i的珠子
if(L[i]==l){//先放等级相同的,因为后面低等级的也会把低等级的放进去
tot++;//i种珠子被放进孔里
for(int k=0;k<=sum;k++){//这一步是必要的
dp[tot][k]=dp[tot-1][k];
}
for(int j=1;j<=p[i];j++){//第i种珠子最多放p[i]个
for(int k=j;k<=sum;k++){//判断还够不够放
dp[tot][k]=max(dp[tot][k],dp[tot-1][k-j]+w[i][j]);
}
}
}
}
}
for(int i=0;i<=sum;i++){
ans=max(ans,dp[tot][i]);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
for(int i=1;i<=6;i++){
cin>>n[i];
for(int j=1;j<=n[i];j++){
int t;
cin>>t;
levNum[t]++;
}
}
cin>>m;//一共有m种珠子
for(int j=1;j<=m;j++){
cin>>L[j];//第j种珠子的等级
cin>>p[j];//第j种珠子的上限
for(int k=1;k<=p[j];k++){
cin>>w[j][k];
}
}
cout<<DP();
return 0;
}