uva--10163(dp,01背包,双肩包)

10163 Storage Keepers

Randy Company has N (1  N  100) storages. Company wants some men to keep them safe. Now

there are M (1  M  30) men asking for the job. Company will choose several from them. Randy

Company employs men following these rules:

1. Each keeper has a number Pi (1  Pi  1000) , which stands for their ability.

2. All storages are the same as each other.

3. A storage can only be lookd after by one keeper. But a keeper can look after several storages. If a

keeper’s ability number is Pi

, and he looks after K storages, each storage that he looks after has

a safe number Uj = Pi  K.(Note: Uj, Pi and K are all integers). The storage which is looked

after by nobody will get a number 0.

4. If all the storages is at least given to a man, company will get a safe line L = minUj

5. Every month Randy Company will give each employed keeper a wage according to his ability

number. That means, if a keeper’s ability number is Pi

, he will get Pi dollars every month. The

total money company will pay the keepers every month is Y dollars.

Now Randy Company gives you a list that contains all information about N, M, P, your task is give

company a best choice of the keepers to make the company pay the least money under the condition

that the safe line L is the highest.

Input

The input file contains several scenarios. Each of them consists of 2 lines:

The first line consists of two numbers (N and M), the second line consists of M numbers, meaning

Pi (i = 1::M). There is only one space between two border numbers.

The input file is ended with N = 0 and M = 0.

Output

For each scenario, print a line containing two numbers L(max) and Y (min). There should be a space

between them.

Sample Input

2 1

7

1 2

10 9

2 5

10 8 6 4 1

5 4

1 1 1 1

0 0

想到了分成两个子问题,先找出最大的安全值L,再去确定达到L所需要的最小花费,一般既满足什么又得怎么样的时候都得分成两个子问题才行,以前也有个题,说什么长度不小于多少的最大子串和,当时也是分成两个子问题来的,先找最大子串和,然后再DP一次保证长度大于多少,扯远了……但是自己也想到了是背包,可是开始自己胡乱定义状态,明明都想到了背包这种经典模型,为何不直接套用方程呢,自己定义的状态乱七八糟根本不对。

求这两个子问题的时候都用到了01背包,看网上的名字也很可爱,叫双肩包~

求解L:

dp[j]=max( min(dp[j-k],man[i]/k , dp[j]); 选和不选两种情况,k是这个人选择的保护的个数,我现在只能先写成二维的再改成滚动数组,要不不知怎的现在还是一下子没法写出来。

求解花费:

dp[j]=min( dp[j-k]+man[i] , dp[j] ) ; k的范围就是man[i]/safe了,这样既满足了第一个条件,又能求出最小的花费。

自己写动归边界问题总是处理不好一直做不对,以后得多加注意。。。啊。这样说估计也没什么用,还得多思考。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<cstring>
#include<vector>
#include<algorithm>
#define INF 0X3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;

typedef long long ll;
typedef unsigned long long llu;
const int maxd=30+5;
const int maxn=100+5;
//==========================
int man[maxd];
int n,m;

bool cmp(int a,int b)
{
    return a>b;
}

int get_L()
{
    int dp[maxn];
    mem(dp,0);
    dp[0]=INF;
    for(int i=1; i<=m; ++i)
        for(int j=n; j>=0; --j)
            for(int k=1; k<=j && man[i]>=k; ++k)
                dp[j]=max( min(dp[j-k],man[i]/k) , dp[j] );
    return dp[n];
}

int get_w(int safe)
{
    if(safe==0) return 0;
    int dp[maxn];
    mem(dp,INF);
    dp[0]=0;
    for(int i=1; i<=m; ++i)
        for(int j=n; j>0; --j)
        {
            int cnt=man[i]/safe;
            for(int k=min(j,cnt); k>0; --k)
            {

                dp[j]=min(dp[j-k]+man[i],dp[j]);
            }
        }
    return dp[n];
}

int main()
{
    freopen("1.txt","r",stdin);
    while(scanf("%d%d",&n,&m)==2 )
    {
        if(n==0 && m==0)
            break;
        for(int i=1; i<=m; ++i)
            scanf("%d",&man[i]);
        sort(man+1,man+m+1,cmp);
        int L=get_L();
        printf("%d %d\n",L,get_w(L));
    }

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-06 18:45:00

uva--10163(dp,01背包,双肩包)的相关文章

USACO Money Systems Dp 01背包

一道经典的Dp..01背包 定义dp[i] 为需要构造的数字为i 的所有方法数 一开始的时候是这么想的 for(i = 1; i <= N; ++i){ for(j = 1; j <= V; ++j){ if(i - a[j] > 0){ dp[i] += dp[i - a[j]]; } } } 状态存在冗余, 输出的时候答案肯定不对 但只需要改一下两个for循环的顺序即可. Source Code: /* ID: wushuai2 PROG: money LANG: C++ */ //

hdu 1561The more, The Better(树形dp&amp;01背包)

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4949    Accepted Submission(s): 2918 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝

poj 3345 Bribing FIPA 【树形dp + 01背包】

Bribing FIPA Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4274   Accepted: 1337 Description There is going to be a voting at FIPA (Fédération Internationale de Programmation Association) to determine the host of the next IPWC (Interna

poj 1837 Balance (dp,01背包)

链接:poj 1837 题意:有一个天平,天平左右两边各有若干个钩子,总共有C个钩子,有G个钩码, 求将钩码挂到钩子上使天平平衡的方法的总数.其中可以把天枰看做一个以x轴0点作为平衡点的横轴 分析:力臂=重量 *臂长 = g[i]*c[j] 当平衡度k=0时,说明天枰达到平衡,k>0,说明天枰倾向右边(x轴右半轴),k<0则左倾 因此可以定义一个 状态数组dp[i][k],意为在挂满前i个钩码时,平衡度为k的挂法的数量. 由于距离c[i]的范围是-15~15,钩码重量的范围是1~25,钩码数量

hdu 4044 GeoDefense (树形dp+01背包)

GeoDefense Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 663    Accepted Submission(s): 267 Problem Description Tower defense is a kind of real-time strategy computer games. The goal of towe

Bone Collector(dp 01背包)

Problem Description Many years ago , in Teddy's hometown there was a man who was called "Bone Collector". This man like to collect varies of bones , such as dog's , cow's , also he went to the grave - The bone collector had a big bag with a volu

HDU 3033 I love sneakers! (DP 01背包+完全背包)

Problem Description After months of hard working, Iserlohn finally wins awesome amount of scholarship. As a great zealot of sneakers, he decides to spend all his money on them in a sneaker store. There are several brands of sneakers that Iserlohn wan

poj 2923 状压dp+01背包

好牛b的思路 题意:一系列物品,用二辆车运送,求运送完所需的最小次数,两辆车必须一起走 解法为状态压缩DP+背包,本题的解题思路是先枚举选择若干个时的状态,总状态量为1<<n,判断这些状态集合里的那些物品能否一次就运走,如果能运走,那就把这个状态看成一个物品.预处理完能从枚举中找到tot个物品,再用这tol个物品中没有交集(也就是两个状态不能同时含有一个物品)的物品进行01背包,每个物品的体积是state[i],价值是1,求包含n个物品的最少价值也就是dp[(1<<n)-1](dp

DP(01背包) UESTC 1218 Pick The Sticks (15CCPC C)

题目传送门 题意:长度为L的金条,将n根金棍尽可能放上去,要求重心在L上,使得价值最大,最多有两条可以长度折半的放上去. 分析:首先长度可能为奇数,先*2.然后除了两条特殊的金棍就是01背包,所以dp[now][j][k]表示当前状态,长度为j,使用了k条特殊金棍获得的最大价值,需要对内存和时间优化. /************************************************ * Author :Running_Time * Created Time :2015/10/2