描述
题解
这道题是0/1背包问题和51Nod 1007 正整数分组的结合。
代码
- 定义一维数组
#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define max_ 5005
#define maxn 250005
int a[max_],dp[maxn];
int n,v,m;
int main()
{
while(scanf("%d",&n)==1&&n>0){
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
int sum=0,k=0;
for(int i=0;i<n;i++){
scanf("%d%d",&v,&m);
for(int j=0;j<m;j++){
a[k++]=v;
}
sum+=v*m;
}
int sum_min=sum/2;
for(int i=0;i<k;i++){
for(int j=sum_min;j>=a[i];j--){
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
}
}
if(sum-dp[sum_min]>=dp[sum_min]){
printf("%d %d\n",sum-dp[sum_min],dp[sum_min]);
}
else{
printf("%d %d\n",dp[sum_min],sum-dp[sum_min]);
}
}
return 0;
}
- 定义二维数组,二维数组两个维度,数据量太大了,WA。
#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define max_ 5005
#define maxn 250005
//
int a[max_],dp[100][3000];
int n,v,m;
int main()
{
while(scanf("%d",&n)==1&&n>0){
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
int sum=0,k=0;
for(int i=0;i<n;i++){
scanf("%d%d",&v,&m);
for(int j=0;j<m;j++){
a[k++]=v;
}
sum+=v*m;
}
int sum_min=sum/2;
for(int i=k-1;i>=0;i--){
for(int j=a[i];j<=sum_min;j++){
dp[i][j]=max(dp[i+1][j],dp[i+1][j-a[i]]+a[i]);
}
}
if(sum-dp[0][sum_min]>=dp[0][sum_min]){
printf("%d %d\n",sum-dp[0][sum_min],dp[0][sum_min]);
}
else{
printf("%d %d\n",dp[0][sum_min],sum-dp[0][sum_min]);
}
}
return 0;
}