标签:http io ar os sp for 数据 问题 代码
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1171
题目大意: n种设备,每种设备价值为v 数量为m 希望 以最小的差距分成两堆 第一堆不能比第二堆少,
开始看完这题让我想起了小时候与朋友一起去摘野果后分野果,就是我先拿一个,拿最大的,朋友再拿一个,也剩下的拿最大的,以此推,不过这样的话测试数据都过不了,
让我知道以前看是公平的分野果的方法其实并不是最好的方法。
这题我用的是多重背包的的思路:多重背包可行性问题么,以价值为费用,以总价值的一半为背包容量。
代码
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[125005];
int main(void)
{
    int n,i,j,k;
    int v[55],m[55];
    while(scanf("%d",&n)==1&&n>=0)
    {
        memset(dp,0,sizeof(dp));
        int s=0;
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&v[i],&m[i]);
            s=s+v[i]*m[i];
        }
        int w=s/2;
        for(i=0;i<n;i++)
        {
            for(j=0;j<=w;j++)
            {
                for(k=0;k<=m[i]&&k*v[i]<=j;k++)
                {
                    dp[j]=max(dp[j],dp[j-k*v[i]]+k*v[i]);
                }
            }
        }
        printf("%d %d\n",s-dp[w],dp[w]);
    }
    return 0;
}
参数
1218MS 780K 733 B
这题可以把多重背包改为01背包
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int v[5005];
int dp[125005];
int main(void)
{
    int i,j,k,n,s;
    int a,b;
    while(scanf("%d",&n)==1&&n>=0)
    {
        k=0;  s=0;
        memset(dp,0,sizeof(dp));
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&a,&b);
            for(j=0;j<b;j++)
            {
                v[k++]=a;
                s=s+a;
            }
        }
        int w=s/2;
        for(i=0;i<k;i++)
        {
            for(j=w;j>=v[i];j--)
            {
                dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
            }
        }
        printf("%d %d\n",s-dp[w],dp[w]);
    }
    return 0;
}
参数
765MS 796K 709 B
快一些,省时。
刚开始接触背包问题 思维有点难以形成,慢慢来。
标签:http io ar os sp for 数据 问题 代码
原文地址:http://www.cnblogs.com/liudehao/p/4101466.html