• HDU 2844 Coins 背包问题 + 二进制优化


    题目大意:某个人有n种硬币,每种硬币价值为v,数量为c,问在总价值不超过m的条件下,最多有多少种组合方式。

    题目思路:

    1.对于某种硬币 如果v*c 大于 m,就意味着无论取多少枚硬币,只要总价值不大于m就取不完该种硬币--完全背包。

    2.如果某种硬币,如果v*c 不大于m,就意味着这是多重背包,因此可以用二进制方法优化一下。

    3.对于不大于m的任意数字j,dp[j]=0代表无法组合成j,dp[j]=1 代表可以组合成j,dp[j]=dp[j]|dp[j-v[i]*k](k为选择第i种硬币的数量)。

    二进制优化:1,2,4,8……可以组合成任意数,将十进制数字1,2,4,8……转化成二进制

    1

    10

    11

    100

    ……

    我们可以发现1,2,4,8……等数字的二进制每一位上都可以组合形成0或1,因此可以组合成其他任意数字。

    #include<cstdio>
    #include<stdio.h>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<cstring>
    #include<vector>
    #include<queue>
    #define INF 0x3f3f3f3f
    #define MAX 1000005
    
    using namespace std;
    
    int dp[MAX],v[MAX],c[MAX],n,m;
    
    int main()
    {
        int i,j,k;
        while(scanf("%d%d",&n,&m),n+m)
        {
            for(i=1;i<=n;i++)
                scanf("%d",&v[i]);
            for(i=1;i<=n;i++)
                scanf("%d",&c[i]);
            memset(dp,0,sizeof(dp));
            dp[0]=1;
            for(i=1;i<=n;i++)
            {
                if(c[i]*v[i] >= m)
                {
                    for(j=v[i];j<=m;j++)//完全背包
                        dp[j]=dp[j]|dp[j-v[i]];
                }
    
                else
                { 
                    for(k=1;k<=c[i]/2;k*=2)//二进制优化
                    {
                        for(j=m;j>=v[i]*k;j--)//多重背包
                        {
                            dp[j]=dp[j]|dp[j-v[i]*k];
                        }
                    }
    
                    k=c[i]-k+1;
                    for(j=m;j>=v[i]*k;j--)
                        dp[j]=dp[j]|dp[j-v[i]*k];
                }
            }
            int ans=0;
            for(i=1;i<=m;i++)
                if(dp[i])
                ans++;
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    codeforce666A_dp
    杭电1789_贪心
    杭电2059_记忆化搜索
    杭电1503_输出最长公共子序列
    杭电1501_dfs和记忆化搜索
    杭电1081_二维dp
    杭电1078_dfs
    coderforce 675C(贪心)
    杭电2571_01背包
    杭电1069_01背包
  • 原文地址:https://www.cnblogs.com/alan-W/p/5755591.html
Copyright © 2020-2023  润新知