UVA-10280-完全DP

题意:给你一些瓶子,有最小和最大装载容量,装载的容量必须在俩者之间,每个瓶子有无限多,对于一个L升的酒,用这些瓶子装的最大体积是多少。

输出剩余的酒量。

L<=1000000L

酒瓶

325ml <= max <= 4500ml

0.95max <= min <= 0.99max

解题思路:

考虑一个这样的瓶子,(min,max),假设在第K个的时候有(k+1)min < kmax(公式1)

这样,在kmin之后的数字就都可以组合出来。当  kmin <= x 时,剩余酒量一定是 0

由 公式1 有 min / (max-min) < k,俩边同时乘上 min

(min*min) / (max-min) < kmin <= x

取max = min / 0.99 (算x的最小值,左边要尽可能大,即分母要尽可能小,max-min最小)

所以根据题目条件可以算出,x最大是441045,也就是超过441045后的状态都不用算,一定可以装满。

#include <string>
#include<iostream>
#include <sstream>
#include<map>
#include<memory.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<math.h>
#include<iomanip>
#include<bitset>
#include"math.h"
namespace cc
{
    using std::cout;
    using std::endl;
    using std::cin;
    using std::map;
    using std::vector;
    using std::string;
    using std::sort;
    using std::priority_queue;
    using std::greater;
    using std::vector;
    using std::swap;
    using std::stack;
    using std::bitset;
    using std::stringstream;
    using std::abs;



    constexpr int BN = 110;
    constexpr int N = 441055;
    constexpr int MAXN = 4550;
    int s[BN];
    int e[BN];
    int vis[MAXN];
    int nums[MAXN];
    int dp[N];


    void solve()
    {
        int n;
        int t = 0;
        cin >> n;
        while (n--)
        {
            if (t != 0)
                cout << endl;
            t++;
            int min = 0x7fffffff;
            int L, num;
            cin >> L >> num;
            L = 1000 * L;
            for (int i = 0; i < num; i++)
            {
                cin >> s[i] >> e[i];
                if ((s[i] * s[i]) / (e[i] - s[i]) < min)
                {
                    min = (s[i] * s[i]) / (e[i] - s[i]);
                }
            }
            if (L >= min)
            {
                cout << 0 << endl;
            }
            else
            {
                int k = 0;
                memset(vis,0,sizeof(vis));
                for (int i=0;i<num;i++) 
                {
                    for (int j=s[i];j<=e[i];j++) 
                    {
                        if (vis[j]==0) 
                        {
                            vis[j] = 1;
                            nums[k++] = j;
                        }
                    }
                }
                memset(dp,0,sizeof(dp));
                for (int i=0;i<k;i++) 
                {
                    for (int j = nums[i];j<=L;j++) 
                    {
                        if (dp[j-nums[i]] + nums[i] > dp[j]) 
                        {
                            dp[j] = dp[j - nums[i]] + nums[i];
                        }
                    }
                }
                cout << L - dp[L] << endl;;
            }
        

        }


    }

};


int main()
{

#ifndef ONLINE_JUDGE
    freopen("d://1.text", "r", stdin);
    //freopen("d://1.out","w",stdout);
#endif // !ONLINE_JUDGE
    cc::solve();

    return 0;
}
原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/11708010.html