hdu3602(变形背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3602

题意是:N个国家,M个飞船,每个国家有人数num,如果上飞船就给联合国value钱,选出某些国家上船且每个国家所有人都必须在同一艘船上,使联合国赚得的钱最多,而且被选出的国家上船的顺序必须和原给的国家顺序一致。

分析:dp[M][K]表示第M条船用了容量K的最大价值,O(NMK)的算法行不通

变形:dp[i]表示获得价值i需要花费最少的代价(用了的船位)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 10010
using namespace std;
int t,n,m,k;
int dp[N];
int cal(int x,int y)
{
    int num=ceil(x*1.0/k);
    if(x+y<=num*k)return x+y;
    //剩余量为k-y,因为前面的船无论还有多少船位,后面的人无法逆序上去了
    else return num*k+y;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        memset(dp,0x3f,sizeof(dp));
        dp[0]=0;
        for(int i=1;i<=n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);a++;
            for(int i=10000;i>=b;i--)
            {
                if(dp[i-b]!=inf)
                dp[i]=min(dp[i],cal(dp[i-b],a));
            }
        }
        int ans;
        for(int i=10000;;i--)
        {
            if(dp[i]<=m*k)
            {
                ans=i;break;
            }
        }
        printf("%d\n",ans);
    }
}

时间: 2025-01-09 03:16:39

hdu3602(变形背包)的相关文章

poj 2392 (Space Elevator) 1276 (Cash Machine)变形背包

这道题跟coins很像,看来楼教主的男人八题果然不简单. 进行coins式的背包处理就好了. 2392 #include<iostream> #include<algorithm> #include<string.h> #include<stdlib.h> #include<stdio.h> #define max(a,b) ((a)>(b)?(a):(b)) typedef long long ll; using namespace st

POj 1170 Shopping Offers(变形背包+进制优化) 100

商店买东西会有优惠政策,使用优惠政策使顾客花的钱尽可能的少. 这道题很有现实背景啊,起初看这道题想的是用规则去优化各种组合情况的物品,并没有想到用背包.因为没有做过"规则"这种物品 还有一点就是接收输入信息的时候若用高维数组很难控制,当时竟然写出了int (*it)[5][5][5][5] 这种东西. 这时,进制优化发挥作用了,其思想类似于康托展开,且因为这个问题并不是直接将位置映射到数集,而是各个不同物品的映射.六进制就够用了.将各个物品映射到一个六进制数字中的每一位,一位上的数字0

tyvj 1057 dp 变形背包

P1057 金明的预算方案 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2006 提高组 第二道 描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:主件 附件电脑 打印机,扫描仪书柜

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

HDU 2955 Robberies --01背包变形

这题有些巧妙,看了别人的题解才知道做的. 因为按常规思路的话,背包容量为浮点数,,不好存储,且不能直接相加,所以换一种思路,将背包容量与价值互换,即令各银行总值为背包容量,逃跑概率(1-P)为价值,即转化为01背包问题. 此时dp[v]表示抢劫到v块钱成功逃跑的概率,概率相乘. 最后从大到小枚举v,找出概率大于逃跑概率的最大v值,即为最大抢劫的金额. 代码: #include <iostream> #include <cstdio> #include <cstring>

poj 2184 0---1背包的变形

这题是0--1背包的变形,对理解0--1背包有很大的帮组 题意:要选一些牛去参见展览,每个牛有幽默.智慧两个选择标准,要求选的这些牛使得幽默和智慧的总和最大且幽默和智慧的每个总和都必须是大于等于0: 刚看的这个题目是时候,知道是一个0--1背包的的题目,但就是不知道怎么来写出状态转移方程,因为题中的两个变量都是有负值的. 看了大牛的解题报告才知道. 我们可以把幽默个变量看成是体积 , 智慧看成是价值. 我们可以把每个牛幽默的值 , 放在一个坐标上,让后整体往右移,使得最小值为 0 , 那么这时候

HDU1114--Piggy-Bank(完全背包变形)

Piggy-Bank   Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 557 Accepted Submission(s): 304 Problem Description Before ACM can do anything, a budget must be prepared and the necessary financial s

HDU 2546 饭卡( 变形01背包)两种思路

中文题:给你n个菜的价格,问m元最少剩下多少.一个条件是:若大于等于5元可以任意刷一次.卡上金额一定要大于5才可以 第一种: dp[j] 用前n-1个物品能否构成j元 变形01背包.若整个菜的价值和都小于m则m-sum; 否则,按升序排序,易证最后用5购买的菜必然是最后一个.先将背包前n-1个放入,看能放入的数据是多少,然后判断m-5后能出现哪些,利用规则替换n物品 #include<iostream> #include<cmath> #include<cstdio>

codeforce Gym 101102A Coins (01背包变形)

01背包变形,注意dp过程的时候就需要取膜,否则会出错. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAXW 15005 #define N 155 #define LL long long #define MOD 1000000007 int w1[N],w2[N]; LL dp1[MAXW],dp2[MAXW]; int main(