Time Limit: 4 Seconds      Memory Limit: 65536 KB


Alice and Bob like eating cake very much. One day, Alice and Bob went to a bakery and bought many cakes.

Now we know that they have bought n cakes in the bakery. Both of them like delicious cakes, but they evaluate the cakes as different values. So they decided to divide those
cakes by following method.

Alice and Bob do n / 2 steps, at each step, Alice choose 2 cakes, and Bob takes the cake that he evaluates it greater, and Alice take the rest cake.

Now Alice want to know the maximum sum of the value that she can get.

Input

The first line is an integer T which is the number of test cases.

For each test case, the first line is an integer n (1<=n<=800). Note that n is always an even integer.

In following n lines, each line contains two integers a[i] and b[i], where a[i] is the value of ith cake that Alice evaluates,
and b[i] is the value of ith cake that Bob evaluates. (1<=a[i]b[i]<=1000000)

Note that a[1]a[2]..., a[n] are n distinct integers and b[1]b[2]..., b[n] are n distinct integers.

Output

For each test case, you need to output the maximum sum of the value that Alice can get in a line.

Sample Input

1
6
1 6
7 10
6 11
12 18
15 5
2 14

Sample Output

28

题意:有n个球,两个人玩游戏,每次选出两个球,B会选出他认为球的价值比较大的,会挑走一个球,然后A会得到另一个球的价值,问怎样取能使A获得的价值最大。

思路:可以先按B所认为的价值从大到小排序,那么对于任意前m件物品,A可以得到m/2件,然后设dp[i][j]表示前i件物品A取出j件最多获得的价值,那么当循环到前第i件时有两种转移形式,一种是这一件不取,那么前i-1件就要取j件,否则就要取j-1件,即dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+c[i].a);

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x7fffffff
#define maxn 810
struct node{
int a,b;
}c[maxn]; bool cmp(node a,node b){
return a.b>b.b;
}
int dp[maxn][maxn]; int main()
{
int n,m,i,j,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d",&c[i].a,&c[i].b); }
sort(c+1,c+1+n,cmp);
memset(dp,-1,sizeof(dp));
dp[1][0]=0;
for(i=2;i<=n;i++){
dp[i][0]=0;
for(j=1;j<=i/2;j++){
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+c[i].a); }
}
printf("%d\n",dp[n][n/2]);
}
}

还有两种是贪心的解法,一个是从前往后贪心,还有一个是从后往前贪心,两者的本质是一样的。我们考虑从后往前贪心,因为不管A所选择的两个数是什么,都是B先选,所以我们可以先把n个数据按b为第一关键字从大到小排序,按a从大到小排序。那么不管我们取出哪两个数,B都是取排在前面的数,题目等价于有n个数,B按顺序取对其来说价值最大的数,A尽可能多的取得对它来说价值大的数。那么我们考虑B取法的规律,前1个数,B至少取1个,前3个数,B至少取2个,前5个数,B至少取3个....前n(n为奇数)个数,B至少取n/2+1个,所以我们可以推出前1个数必由B取,前3个数A至多取1个,前5个数,A至多取3个...那么我们便可进一步推出,后1个数,A至少取1个,后3个数,A至少取2个,后5个数,B至少取3个,那么我们可以从后往前每次把2个数放入set里,然后把set里最大的数取出,加上该值就行了。

代码一:(从后往前推)

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 1000
struct node1{
int num;
}temp,temp1;
bool operator<(node1 c,node1 d){
return c.num>d.num;
}
set<node1>myset;
set<node1>::iterator it; struct node{
int a,b;
}c[maxn];
bool cmp(node c,node d){
return c.b>d.b;
} int main()
{
int n,m,i,j,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d",&c[i].a,&c[i].b);
}
sort(c+1,c+1+n,cmp);
if(n==2){
printf("%d\n",c[2].a);
continue;
}
int sum=c[n].a;
myset.clear();
for(i=n-1;i>=1;i--){
node1 temp;
temp.num=c[i].a;
myset.insert(temp);
if(i%2==0){
it=myset.begin();
sum+=(*it).num;
myset.erase(*it);
}
}
printf("%d\n",sum);
}
return 0;
} /*
1
6
1 6
7 10
6 11
12 18
15 5
2 14
*/

代码二:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 1000
set<int>myset;
set<int>::iterator it; struct node{
int a,b;
}c[maxn];
bool cmp(node c,node d){
return c.b>d.b;
} int main()
{
int n,m,i,j,T,sum1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
sum1=0;
for(i=1;i<=n;i++){
scanf("%d%d",&c[i].a,&c[i].b);
sum1+=c[i].a;
}
sort(c+1,c+1+n,cmp);
if(n==2){
printf("%d\n",c[2].a);
continue;
}
int sum=0;
myset.clear();
for(i=1;i<=n;i++){
myset.insert(c[i].a);
if(i%2==1){
it=myset.begin();
sum+=*it;
myset.erase(it);
}
}
printf("%d\n",sum1-sum);
}
return 0;
} /*
1
6
1 6
7 10
6 11
12 18
15 5
2 14
*/

zoj3905 Cake的更多相关文章

  1. Windows 7上执行Cake 报错原因是Powershell 版本问题

    在Windows 7 SP1 电脑上执行Cake的的例子 http://cakebuild.net/docs/tutorials/getting-started ,运行./Build.ps1 报下面的 ...

  2. 2015暑假多校联合---Cake(深搜)

    题目链接:HDU 5355 http://acm.split.hdu.edu.cn/showproblem.php?pid=5355 Problem Description There are m s ...

  3. Scalaz(15)- Monad:依赖注入-Reader besides Cake

    我们可以用Monad Reader来实现依赖注入(dependency injection DI or IOC)功能.Scala界中比较常用的不附加任何Framework的依赖注入方式可以说是Cake ...

  4. uva10167 Birthday Cake

    Lucy and Lily are twins. Today is their birthday. Mother buys a birthday cake for them. Now we put t ...

  5. HDU 4762 Cut the Cake(公式)

    Cut the Cake Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  6. Brute Force --- UVA 10167: Birthday Cake

     Problem G. Birthday Cake  Problem's Link:http://uva.onlinejudge.org/index.php?option=com_onlinejudg ...

  7. 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest, B. Layer Cake

    Description Dasha decided to bake a big and tasty layer cake. In order to do that she went shopping ...

  8. hdu acmsteps 2.1.3 Cake

    Cake Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...

  9. ZOJ 3905 Cake ZOJ Monthly, October 2015 - C

    Cake Time Limit: 4 Seconds      Memory Limit: 65536 KB Alice and Bob like eating cake very much. One ...

随机推荐

  1. MySQL常用字符串函数和日期函数

    数据函数 SELECT ABS(-8); /*绝对值*/ SELECT CEILING(9.4); /*向上取整*/ SELECT FLOOR(9.4); /*向下取整*/ SELECT RAND() ...

  2. PC个人隐私保护小方法

    前言 近期爆出了腾讯读取用户浏览器浏览记录的消息.话不过说直接上图,懂的自然懂. 网上也有详细的分析文章,不管它读取后用来做什么,在你不知情的情况下读取了你的浏览器浏览记录,你说气不气. 虽然在整体大 ...

  3. ps 2020 下载

    一款极具实用价值的作图软件--ps,由于正版价格昂贵,所以这里分享破解版的资源.b话少说,下面是下载链接和安装步骤: 下载链接: 百度网盘链接:https://pan.baidu.com/s/1XPf ...

  4. ctfhub技能树—sql注入—布尔盲注

    打开靶机 查看页面信息 开始试验,查看返回信息 此题存在一个问题,如果没有数据,也是返回query_success 如此一来,就无法使用and组合进行注入,在看了其他大佬的解题过程后,知道了可以使用& ...

  5. C#实现一个弹窗监控小程序

    一..实现弹窗淡入淡出等效果即弹窗自动关闭 技术要点: 1.弹窗效果(淡入淡出,自下而上滑入)使用WIN API实现 2.弹出的窗体在一定时间后,自动关闭使用一个timer实现,弹窗开始是,打开tim ...

  6. python3.8.1安装cx_Freeze

    按照官网的提示命令python -m pip install cx_Freeze --upgrade安装,不成功,报了一个错误,说cx_Freeze找不到需要的版本,还有一些警告说PIP需要升级,没理 ...

  7. C# 关机/重启/注销计算机

    一.调用 shutdown.exe 执行操作 调用 shutdown.exe 执行计算机关机.重启.注销操作,还可以设置多长时间后执行操作,代码如下: 1 /// <summary> 2 ...

  8. 理解js闭包9大使用场景

    1.返回值(最常用) //1.返回值 最常用的 function fn(){ var name="hello"; return function(){ return name; } ...

  9. 小白也能看懂的ACID与隔离级别

    前言 现如今JAVA开发工程师的数量越来越多,但大多数工程师平时做的工作都是简单的CRUD,当你一直处于这种舒适的环境中不追求进步的时候,如果哪一天你突然想要改变环境,换个工作,去与面试官当面聊技术的 ...

  10. OpenStack各组件的常用命令

    openstack命令 openstack-service restart    #重启openstack服务 openstack endpoint-list        #查看openstack的 ...