题目描述

新一年度的猫狗大战通过SC(星际争霸)这款经典的游戏来较量,野猫和飞狗这对冤家为此已经准备好久了,为了使战争更有难度和戏剧性,双方约定只能选择Terran(人族)并且只能造机枪兵。

比赛开始了,很快,野猫已经攒足几队机枪兵,试探性的发动进攻;然而,飞狗的机枪兵个数也已经不少了。野猫和飞狗的兵在飞狗的家门口相遇了,于是,便有一场腥风血雨和阵阵惨叫声。由于是在飞狗的家门口,飞狗的兵补给会很快,野猫看敌不过,决定撤退。这时飞狗的兵力也不足够多,所以没追出来。

由于不允许造医生,机枪兵没办法补血。受伤的兵只好忍了。555-

现在,野猫又攒足了足够的兵力,决定发起第二次进攻。为了使这次进攻给狗狗造成更大的打击,野猫决定把现有的兵分成两部分,从两路进攻。由于有些兵在第一次战斗中受伤了,为了使两部分的兵实力平均些,分的规则是这样的:1)两部分兵的个数最多只能差一个;2)每部分兵的血值总和必须要尽可能接近。现在请你编写一个程序,给定野猫现在有的兵的个数以及每个兵的血格值,求出野猫按上述规则分成两部分后每部分兵的血值总和。

输入输出格式

输入格式:

第一行为一个整数n(1<=n<=200),表示野猫现在有的机枪兵的个数。以下的n行每行一个整数,表示每个机枪兵的血格(1<=ai<=40)。

输出格式:

一行,为两个整数,表示分成两部分后每部分兵的血值总和

输入输出样例

输入样例#1:

3
35
20
32

输出样例#1:

35 52

说明

TO 狗狗:这道题的数据范围我已经尽量按星际的游戏规则来了,如果你再固执于由于机枪兵的攻击力一定使不能达到某些血格值或者游戏中一定要造农民不能使机枪兵的人数达到200的话,我只能决定将那场猫狗大战的录像公开于世人了!!!

题解

先说正解,我们用f[i][j][k]表示选了前i个兵中j个兵是否可以构成血量为k,之后就转化为一个背包问题的变形,优化一维成为f[i][j]表示选i个兵能否构成j的血量 转移方程 f[i][j]=f[i][j]|f[i-1][j-a[i];边界条件 f[0][0]=1 即选取0个人构成0的血量是可行的。最后统计答案是从sum(所以兵血量和)除以2开始枚举,发现的第一个满足的方案时就输出解。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 100000000
using namespace std;
const int maxn=300;
int a[maxn],sum,dp[maxn][50010];
int main(){int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);sum+=a[i];}dp[0][0]=1;for(int i=1;i<=n;i++)for(int j=i;j>=1;j--)for(int k=sum;k>=a[i];k--)--)//枚举构成的血量,至于为什么这两行要倒叙枚举//就像01背包优化为一维时,就是倒叙枚举,因为物品只有一个,本题的人也各只有一个,所以为避免重复计算,故倒叙枚举; dp[j][k]|=dp[j-1][k-a[i]];//这行就是前面有一个状态可以这个状态就可以int i;for(i=sum/2;i>=0;i--)if(dp[n/2][i])break;printf("%d %d\n",i,sum-i);return 0;
}

现在说一下我开始错误的想法。写在代码上了。

//dp[i][j][k]表示前i个人第一组有j个的第一组的数和第二个的数。
//但这个方程并不对,因为并不是有局部最优推出全局最优(dp性质),可能当前状态这是最优的,但是假设再加上另一个很大的数的时候就不是最优的了
//它可能不是由上一个最优的解转移过来,而是由不是最优的转移过来,加上这个数之后就是最优的了,这不满足dp的性质,所以不行。这和午餐这题很相似。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 100000000
using namespace std;
const int maxn=300;
int a[maxn],dp[maxn][maxn][5],ans=inf,ansx,ansy;
int main(){int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);sort(a+1,a+n+1);for(int i=1;i<=n;i++)for(int j=0;j<=i;j++){if(abs(i-j*2)>1) continue;else if(abs(i-j*2-1)>1) dp[i][j][1]=dp[i-1][j-1][1]+a[i],dp[i][j][2]=dp[i-1][j-1][2];else if(abs(i-j*2+1)>1)  dp[i][j][2]=dp[i-1][j][2]+a[i],dp[i][j][1]=dp[i-1][j][1]; else if(abs(dp[i-1][j][1]-dp[i-1][j][2]-a[i])<abs(dp[i-1][j-1][1]+a[i]-dp[i-1][j-1][2])){dp[i][j][2]=dp[i-1][j][2]+a[i];dp[i][j][1]=dp[i-1][j][1]; }else dp[i][j][1]=dp[i-1][j-1][1]+a[i],dp[i][j][2]=dp[i-1][j-1][2];}for(int i=0;i<=n;i++)if(abs(n-i*2)<=1){if(ans>abs(dp[n][i][1]-dp[n][i][2])){ans=min(ans,dp[n][i][1]-dp[n][i][2]);ansx=dp[n][i][1];ansy=dp[n][i][2];}}printf("%d\n%d\n",ansx,ansy);return 0;
}

Description

上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂。这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭。由于每个人的口味(以及胃口)不同,所以他们要吃的菜各有不同,打饭所要花费的时间是因人而异的。另外每个人吃饭的速度也不尽相同,所以吃饭花费的时间也是可能有所不同的。 THU ACM小组的吃饭计划是这样的:先把所有的人分成两队,并安排好每队中各人的排列顺序,然后一号队伍到一号窗口去排队打饭,二号队伍到二号窗口去排队打饭。每个人打完饭后立刻开始吃,所有人都吃完饭后立刻集合去六教地下室进行下午的训练。 现在给定了每个人的打饭时间和吃饭时间,要求安排一种最佳的分队和排队方案使得所有人都吃完饭的时间尽量早。 假设THU ACM小组在时刻0到达十食堂,而且食堂里面没有其他吃饭的同学(只有打饭的师傅)。每个人必须而且只能被分在一个队伍里。两个窗口是并行操作互不影响的,而且每个人打饭的时间是和窗口无关的,打完饭之后立刻就开始吃饭,中间没有延迟。 现在给定N个人各自的打饭时间和吃饭时间,要求输出最佳方案下所有人吃完饭的时刻。

Input

第一行一个整数N,代表总共有N个人。 以下N行,每行两个整数 Ai,Bi。依次代表第i个人的打饭时间和吃饭时间。

Output

一个整数T,代表所有人吃完饭的最早时刻。

Sample Input

5
2 2
7 7
1 3
6 4
8 5

Sample Output

17

HINT

方案如下:

窗口1: 窗口2:
7 7 1 3
6 4 8 5
2 2

【限制】
所有输入数据均为不超过200的正整数。

现在说说和这题类似的午餐问题。错误的想法是dp[i][j]前i个人中,j个放在第一组。错误原因和上面一样。上一题枚举血量,所以这一题枚举时间。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=500100;
int n,sum[maxn],sum1[maxn];
int dp[maxn];
struct node{int u,v;
}a[maxn];
bool cmp(node a,node b){return a.v>b.v;
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&a[i].u,&a[i].v);}sort(a+1,a+n+1,cmp);for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i].u;memset(dp,127,sizeof(dp));dp[0]=0;for(int i=1;i<=n;i++){for(int j=sum[i];j>=0;j--){if(j>=a[i].u)dp[j]=min(max(dp[j-a[i].u],j+a[i].v),max(dp[j],sum[i]-j+a[i].v));elsedp[j]=max(dp[j],sum[i]-j+a[i].v);}}int ans=2147483647;for(int i=1;i<=sum[n];i++)ans=min(ans,dp[i]); printf("%d\n",ans);return 0;
}

【洛谷1489】猫狗大战【BZOJ1899】【ZJOI2004】Lunch午餐相关推荐

  1. BZOJ1899 [Zjoi2004]Lunch 午餐 贪心+DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1899 题解 如果只有一个窗口,那么可以这样考虑:因为最后一个人打完饭的时间是固定的,那么不如就 ...

  2. Bzoj1899: [Zjoi2004]Lunch 午餐

    题面 传送门 Sol 首先显然吃饭久的要排在前面 之后再来分配队伍,设\(f[i][j]\)表示到第\(i\)个人,\(A\)队伍要等\(j\)的最小吃完饭时间 那么就是一个简单的背包吧... # i ...

  3. 【BZOJ1899】[Zjoi2004]Lunch 午餐 贪心+DP

    [BZOJ1899][Zjoi2004]Lunch 午餐 Description 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时 ...

  4. 洛谷P1489 猫狗大战

    题目描述 新一年度的猫狗大战通过SC(星际争霸)这款经典的游戏来较量,野猫和飞狗这对冤家为此已经准备好久了,为了使战争更有难度和戏剧性,双方约定只能选择Terran(人族)并且只能造机枪兵. 比赛开始 ...

  5. 洛谷 P7960 [NOIP2021] 报数

    PS:如果读过题了可以跳过题目描述直接到题解部分 提交链接:洛谷 P7960 [NOIP2021] 报数 题目 题目描述 报数游戏是一个广为流传的休闲小游戏.参加游戏的每个人要按一定顺序轮流报数,但如 ...

  6. 【寒假每日一题】洛谷 P6367 [COCI2006-2007#6] PRASE

    题目链接:P6367 [COCI2006-2007#6] PRASE - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述 孩子们正在餐桌旁吃午餐,共有 n 份食物,孩子们会按照 ...

  7. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  8. 洛谷 P1142 轰炸

    洛谷 P1142 轰炸 题目描述 "我该怎么办?"飞行员klux向你求助. 事实上,klux面对的是一个很简单的问题,但是他实在太菜了. klux要想轰炸某个区域内的一些地方,它们 ...

  9. 洛谷 P1387 最大正方形

    P1387 最大正方形 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=10 ...

  10. 洛谷P2763 试题库问题

    题目:https://www.luogu.org/problemnew/show/P2763 题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性. ...

最新文章

  1. 瞎了,苹果说这两个Logo过于相似而提起诉讼...
  2. [以太坊源代码分析] I.区块和交易,合约和虚拟机
  3. operator-sdk安装脚本整理
  4. flutter 自定义键盘_掘金 AMA:听闲鱼客户端架构师邬吉风聊 Flutter 和移动端开发那些事...
  5. 列表合并变种题,map()函数扩展
  6. android 应用切换滑动,Android应用中利用ViewPager实现多页面滑动切换效果示例
  7. 基于CAS的低时延队列实现(原理示例)
  8. 创业项目筹备了两个多月,确实不容易
  9. 杭电计算机组成原理实验RISC-V 实验 实现运算及传送指令的CPU设计实验 实现访存指令的CPU设计实验 实现转移指令的CPU设计实验
  10. 计算机每次启动都要系统修复,win7电脑每次开机都要重启路由器才能上网的修复方法...
  11. Java IO流源码学习之二(Buffered字节流)
  12. 湖北武汉安全员C证报考条件考试流程一览 秋禾火
  13. CMakeLists.txt链接库的基本套路
  14. 金融机构业务连续性管理
  15. el-admin框架简单解析-快速入门(前端部分)
  16. VS对数据库里表的查询
  17. 【王道考研】操作系统 笔记 第二章上 进程调度
  18. 设计模式之代理模式(C++)
  19. 技术人员的发展之路 - 陈皓
  20. 接口管理工具Yapi禁用注册功能的配置解决方案

热门文章

  1. 【亲测有效】C盘扩展卷灰色的解决办法
  2. 你需要了解的JS框架 用途:构建数
  3. 【邮件处理】邮件eml文件解析
  4. 做网站必备!该文介绍下国内服务器与国外服务器的区别
  5. 【华为机试】鸡蛋放在篮子里
  6. cpufreq schedutil原理剖析
  7. MCS51 系列单片机的中央处理器(CPU)
  8. java计算机毕业设计远程教学系统录屏源程序+mysql+系统+lw文档+远程调试
  9. 代理模式——保护代理(三)
  10. 锂离子电池种类介绍和分类