zoukankan      html  css  js  c++  java
  • poj 1276(多重背包+最接近)

    http://www.cnblogs.com/rainydays/archive/2013/03/08/2950258.html

    http://www.cnblogs.com/ziyi--caolu/p/3216827.html

    第一种:

    邻接+统计数量

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <vector>
    #include <iterator>
    #include <set>
    #include <map>
    #include <sstream>
    using namespace std;
    
    #define mem(a,b) memset(a,b,sizeof(a))
    #define pf printf
    #define sf scanf
    #define spf sprintf
    #define pb push_back
    #define debug printf("!
    ")
    #define MAXN 1010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #define LL long long
    #define ALL(x) x.begin(),x.end()
    #define INS(x) inserter(x,x.begin())
    #define pqueue priority_queue
    #define INF 0x3f3f3f3f
    
    int cash,n,sum;
    
    int c[15],w[15],used[100005];
    
    bool f[100005];
    
    void mubag()
    {
        int i,j;
        mem(f,false);
        f[0] = true;
        //debug;
        for(i=0;i<n;i++)
        {
            mem(used,0);
            for(j = w[i];j<=cash;j++)
            {
                if(f[j-w[i]] && !f[j] && used[j-w[i]]<c[i])
                {
                    f[j] = true;
                    used[j] = used[j-w[i]]+1;
                    //pf("f%d cnt%d
    ",j,used[j]);
                }
            }
        }
    }
    
    int main()
    {
        int i,j;
        while(~sf("%d%d",&cash,&n))
        {
            for(i=0;i<n;i++)
            {
                sf("%d%d",&c[i],&w[i]);
            }
            mubag();
            for(i=cash;i>=0;i--)
            {
                if(f[i])
                {
                    pf("%d
    ",i);
                    break;
                }
            }
        }
        return 0;
    }

    第二种:

    二进制拆分+01背包

    value = weight

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int dp[110000],t[30000],s[2000][2];
    int main()
    {
        int cash,n;
        while(scanf("%d%d",&cash,&n)>0)
        {
             int cnt=0;
             //memset(t,0,sizeof(t));
             for(int i=1;i<=n;i++)
             {
                     scanf("%d%d",&s[i][0],&s[i][1]);
                     int k=1;
                     if(s[i][0]==0||s[i][1]==0)
                     continue;
                     while(s[i][0]-k>0)
                     {
                            t[cnt++]=k*s[i][1];
                            s[i][0]-=k;
                            k*=2;
                     }
                     t[cnt++]=s[i][0]*s[i][1];
             }
             memset(dp,0,sizeof(dp));
             for(int i=0;i<cnt;i++)
             {
                     for(int j=cash;j>=t[i];j--)
                     if(dp[j]<dp[j-t[i]]+t[i])
                     dp[j]=dp[j-t[i]]+t[i];
             }
             printf("%d
    ",dp[cash]);
        }
        return 0;
    }

    第三种:

    完全背包+统计数量

    value = weight

    基本和第一种一样,速度也一样,更清晰一点

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    int dp[110000],num[100100],s[2000][2];
    int main()
    {
        int cash,n;
        while(scanf("%d%d",&cash,&n)>0)
        {
             int cnt=0;
             for(int i=1;i<=n;i++)
             {
                     scanf("%d%d",&s[i][0],&s[i][1]);
             }
             memset(dp,0,sizeof(dp));
             for(int i=1;i<=n;i++)
             {
                     memset(num,0,sizeof(num));
                     for(int j=s[i][1];j<=cash;j++)
                     if(dp[j]<dp[j-s[i][1]]+s[i][1]&&num[j-s[i][1]]<s[i][0])
                     {
                            dp[j]=dp[j-s[i][1]]+s[i][1];
                            num[j]=num[j-s[i][1]]+1;
                     }
             }
             printf("%d
    ",dp[cash]);
        }
        return 0;
    }
  • 相关阅读:
    Redis知识梳理(1)当我们谈到双写一致性的时候,我们在谈什么?
    多线程知识梳理(4),当我们谈到volatile的时候,我们在谈什么?
    多线程知识梳理(3),当我们谈到CAS的时候,我们在谈什么?
    多线程知识梳理(2),当我们谈到synchronized关键字的时候,我们在谈什么?
    多线程知识梳理(1):当我们谈到指令乱序的时候,在谈什么?
    LeetCode刷题记录本
    “退格”转义字符使用实例
    “逻辑异或”进行数值交换的过程分析
    ConcurrentHashMap源码走读
    Netty如何监控内存泄露
  • 原文地址:https://www.cnblogs.com/qlky/p/5639013.html
Copyright © 2011-2022 走看看