zoukankan      html  css  js  c++  java
  • poj 1276 Cash Machine(多重背包问题)

    最近在学习背包九讲,呃,现在刚看到多重背包问题,还是有点慢啊。

    这题是典型的多重背包问题,题意是,给你n中面值不同的纸币,每种面值为c,每种有n[i]张,给你一定的数额,问有这些纸币能组合出小于等于所给面值的最大钱数。

    但是题目中给的数据范围有点大,如果按基本的多重背包来做会TLE,看了《背包九讲》中利用二进制思想的优化,没看懂伪代码,搜了个代码慢慢研究,终于有点明白了,不过还是不明白为什么要按1 , 2, 4, ……2^(k-1) , n - 2^k  这样确定系数,呃,还是慢慢想吧~~

    代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #define maxm 102
    #define maxn 100005
    using namespace std ;
    
    int val[maxm] , dp[maxn] ;
    
    int main()
    {
        int count , i , j , v , c , n , cash ;
    
        while ( scanf ( "%d%d" , &cash , &n ) != EOF )
        {
            count = 0 ;
            for ( i = 0 ; i < n ; i++ )
            {
                scanf ( "%d%d" , &v , &c );
                int k = 1;
                while ( v - k >= 0 )//利用二进制思想拆分
                {
                    val[count++] = k * c;
                    v -= k ;
                    k *= 2 ;
                }
                if ( v )
                val[count++] = v * c ;
            }
            memset( dp , 0 , sizeof( dp ));//初始化
            dp[0] = 1 ;//能组成的最小的面值为0 , 所以0初始化为1
            for ( i = 0 ; i < count ; i++ )//0-1背包
            {
                for ( j = cash ; j >= val[i] ; j-- )
                if ( dp[j - val[i]] )
                dp[j] = 1 ;
            }
            int k = cash ;
            while ( !dp[k] ) k--;
            printf ( "%d\n" , k );
        }
        return 0;
    }
  • 相关阅读:
    fastjson反序列化漏洞研究(上)
    csv注入复现代码
    day24-python之面向对象
    day23-python之日志 re模块
    day22-python之模块
    day21-python模块
    day20-python之装饰器
    day18-python之迭代器和生成器
    day17-python之文件操作
    day16-python之函数式编程匿名函数
  • 原文地址:https://www.cnblogs.com/misty1/p/2540877.html
Copyright © 2011-2022 走看看