HDU 4341 Gold miner(分组背包)

原创 2014年10月31日 16:24:07

HDU 4341 Gold miner(分组背包)

http://acm.hdu.edu.cn/showproblem.php?pid=4341

题意:

       一个人在原点(0,0)抓金子,每块金子是二维坐标平面的一个点(x,y)且y>0. 每块金子有一个价值v和获得需要的时间t。如果多个金子在一条从原点射出的直线上,那只能先抓近的,再抓远的。求在给定时间T下,所能获得的最大价值。

分析:

       首先想想如果所有点都不共线是什么情况? 就是在给定时间T内要获取最大的价值和的点, 且所有点都可以任意选取. 那么这就是一个01背包问题. 不过如果存在共线的点,那么如何处理呢?

       我们把所有共(从原点射出的)直线的点分成1组, 然后每个组内只能选1个点. 比如如果你选了该组第i远的点, 那么你就必须把第1个第2个..第i-1 和第i个点都选了. 所以每组i点的花费和价值都是前面所有点的累加和.

       现在的问题就变成了分组背包问题了: 对于每个给定的组, 组内最多只能选1个物品, 问你能获得的最大价值和.

       我们令dp[i][j]==x表示只选前i组的物品,总花费<=j时能获得的最大价值==x.

       初始化: dp全为0.

       状态转移: dp[i][j] = max( dp[i-1][j] , dp[i-1][j-cost[k]]+val[k]) 其中cost[k]和val[k]是第i组物品中的第k个物品的花费和价值.

       最终所求: dp[n][T].

       注意程序实现的3层循环不能互换顺序, 因为要保证滚动数组的情况下, 实现上述的状态转移方程.

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=200+5;

struct Point
{
    int x,y;
    int cost,val;
    bool operator<(const Point &rhs)const//极角排序
    {
        return x*rhs.y-y*rhs.x<0 || (x*rhs.y-y*rhs.x==0 && y<rhs.y);
    }
    bool operator==(const Point &rhs)const//共线判断
    {
        return x*rhs.y-y*rhs.x==0;
    }
}p[maxn];

int N,T;
int n;        //多少组
int num[maxn];//num[i]表示第i组的物品数
int cost[maxn][maxn];//cost[i][j]==x表示第i组第j个物品的花费
int val[maxn][maxn]; //cost[i][j]==x表示第i组第j个物品的价值
int dp[40000+5];

int main()
{
    int n,kase=0;
    while(scanf("%d%d",&N,&T)==2)
    {
        //读取输入
        for(int i=0;i<N;i++)
            scanf("%d%d%d%d",&p[i].x,&p[i].y,&p[i].cost,&p[i].val);
        sort(p,p+N);

        //原始物品分成n组,每组只取1个
        n=1;
        num[n]=1;
        cost[n][num[n]]=p[0].cost;
        val[n][num[n]]=p[0].val;
        for(int i=1;i<N;i++)
        {
            if(p[i]==p[i-1])//共线
            {
                num[n]++;
                cost[n][num[n]]=cost[n][num[n]-1]+p[i].cost;
                val[n][num[n]]=val[n][num[n]-1]+p[i].val;
            }
            else//不共线
            {
                n++;
                num[n]=1;
                cost[n][num[n]]=p[i].cost;
                val[n][num[n]]=p[i].val;
            }
        }

        //分组背包过程
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        for(int j=T;j>=0;j--)
        for(int k=1;k<=num[i];k++)
            if(j>=cost[i][k])
            dp[j] = max(dp[j], dp[j-cost[i][k]]+val[i][k]);

        printf("Case %d: %d\n",++kase,dp[T]);
    }
    return 0;
}

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

HDU4341:Gold miner(分组背包)

Gold miner Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total...
  • junior19
  • junior19
  • 2017年02月01日 00:50
  • 78

HDU4341——Gold miner(分组背包)

Gold miner Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot...
  • say_c_box
  • say_c_box
  • 2017年03月23日 10:18
  • 291

hdu 4341 分组背包

http://acm.hdu.edu.cn/showproblem.php?pid=4341 Problem Description Homelesser likes playing Gol...
  • u013573047
  • u013573047
  • 2015年02月05日 10:15
  • 568

hdu 4341(分组背包(好题))

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4341 分组背包问题, 由于一条直线上的要按照顺序取, 如果一条直线上有n个金矿, 对于这条直线则有n...
  • tjdrn
  • tjdrn
  • 2013年08月04日 21:40
  • 606

hdu1712 分组背包问题

问题 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量...
  • u013573047
  • u013573047
  • 2014年12月20日 15:25
  • 956

HDU_01背包系列

HDU 01背包系列持续更新中……
  • jhgkjhg_ugtdk77
  • jhgkjhg_ugtdk77
  • 2016年07月22日 12:22
  • 2471

HDU_完全背包系列

HDU 完全背包系列持续更新中……
  • jhgkjhg_ugtdk77
  • jhgkjhg_ugtdk77
  • 2016年07月23日 12:01
  • 1300

HDU2602/HDU1114/HDU2191(重新整理一下01背包,完全背包,多重背包)

好长时间不做背包的问题,有一点遗忘,现在把这些问题整理一下~ 一.01背包(HDU2602) 题目:http://acm.hdu.edu.cn/showproblem.php?pid=2602 题意就...
  • riba2534
  • riba2534
  • 2017年01月11日 13:24
  • 822

分组背包及树上分组背包

【人生相关】好困啊QAQ 小伙伴们明天都去APIO了 当初脑残没报名= = 蛮后悔的= = 但想想2800rmb 也就还好了 美好的一天从一道树形dp开始 昨天看了下以前写的分组背包 树形dp ...
  • yxr0105
  • yxr0105
  • 2016年05月04日 09:52
  • 404

HDU 4341 判断共线+背包

题意:黄金矿工的意思,每个点有价值和时间,如果共线得从最近的开始取,问求时间t內取到的最大价值。 这题把共线的情况看成一组,要取某个点的话必须把跟这个点共线并且与原点距离在这个点之前的点取到。所以把...
  • h6363817
  • h6363817
  • 2013年06月26日 09:58
  • 810
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 4341 Gold miner(分组背包)
举报原因:
原因补充:

(最多只允许输入30个字)