内存限制:128 MB时间限制:1 S标准输入输出

 

题目描述

自从上次AWM打了整个弹夹的子弹都没有打中一枪后,小明被队友叫去当医疗兵。小明有个癖好,就是只收集医疗包和饮料。假设我们已经知道小明即将被子弹射中的伤害序列,问小明最多能撑到第几颗子弹,即被第几颗子弹射中后,还是活着的(血量大于0就算活着)。一开始小明的血量为满(100),医疗包只能在血量低于70使用,使用后血量会直接恢复到70,饮科可以在任意血量下使用,使用后血量增加30。

 

输入格式

多组测试数据,首先第一行一个整数T,代表测试数据组数。1≤T≤100。
每组测试数据有a,b,n,代表有a个医疗包。b瓶饮料,n个子弹即将射中小明,接下来有n个数,第i个数xi代表第i颗子弹对小明的伤害。0≤a,b≤100,1≤n,xi≤100,a,b,n,xi均是非负整数。

 

输出格式

对于每组数据输出一个数c,代表小明最多撑到第c颗子弹。

 

输入样例 复制

3
1 1 3
20 90 70
0 0 1
100
0 0 2

10 90

 

输出样例 复制

2
0
1

 

问题 D: 医疗兵_C语言

 

思路:

动态规划,有七种转移:

  1. 用1个医疗包

  2. 用1个医疗包和1个饮料

  3. 用1个饮料

  4. 用2个饮料

  5. 用3个饮料

  6. 用4个饮料

  7. 什么都不用

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX(a,b,c,e,d,f,g) max(a,max(b,max(c,max(d,max(e,max(f,g))))))
#define _INF -0x7fffffff
using namespace std;
int dp[105][105][105];
int que[105];
int n;
int t;
int main()
{
cin>>t;
while(t--)
{
int a,b;
memset(dp,0,sizeof(dp));
memset(que,0,sizeof(que));
scanf("%d%d%d",&a,&b,&n);
for(int i=1;i<=n;++i)
scanf("%d",&que[i]);
for(int i=0;i<=a;++i)
for(int j=0;j<=b;++j)
dp[0][i][j]=100;
int t=0,ans=0;
for(int i=1;i<=n;++i)
{
int c=t;
for(int j=0;j<=a;++j)
{
for(int k=0;k<=b;++k)
{
dp[i][j][k]=MAX(
dp[i-1][j][k]-que[i],
(j>0&&dp[i-1][j-1][k]>0&&dp[i-1][j-1][k]<=70)? 70-que[i]:_INF,
(dp[i-1][j-1][k-1]>0&&j>0&&k>0&&dp[i-1][j-1][k-1]<=70)? 100-que[i]:_INF,
(k>0&&dp[i-1][j][k-1]>0)? (dp[i-1][j][k-1]>70? 100-que[i]:dp[i-1][j][k-1]+30-que[i]):_INF,
(k>1&&dp[i-1][j][k-2]>0)? (dp[i-1][j][k-2]>40? 100-que[i]:dp[i-1][j][k-2]+60-que[i]):_INF,
(k>2&&dp[i-1][j][k-3]>0)? (dp[i-1][j][k-3]>10? 100-que[i]:dp[i-1][j][k-3]+90-que[i]):_INF,
(k>3&&dp[i-1][j][k-4]>0)? (100-que[i]):_INF
);
if(dp[i][j][k]>0)
t++;
}
}
if(c!=t)
ans=max(ans,i);
}
cout<<ans<<endl;
}
return 0;
}