uva 6757 Cup of Cowards(中途相遇法,貌似)

uva 6757 Cup of Cowards
Cup of Cowards (CoC) is a role playing game that has 5 di?erent characters (Mage, Tank, Fighter,
Assassin and Marksman). A team consists of 5 players (one from each kind) and the goal is to kill a
monster with L life points. The monster dies if the total damage it gets is at least L. Each character
has a certain number of allowed hits, each hit has a certain damage and a certain cost (the cost and
damage might be di?erent for each character). The team wants to kill the monster using the minimum
cost so they can perform better in later missions. They want your help to ?nd the minimum cost they
will pay to kill the monster and the damage they should incur on it.
Input
Your program will be tested on one or more test cases. The ?rst line of the input will be a single
integer T, the number of test cases (1 ≤ T ≤ 100). Followed by the test cases, the ?rst line of each
test case contains 1 integer L (0 ≤ L ≤ 1012) representing the life points of the monster. Followed by
5 lines, each one contains 3 integers separated by a single space H D C representing the maximum
number of hits, the damage by each hit and the cost of each hit by one of the characters, respectively
(0 ≤ H ≤ 1, 000), (0 ≤ D, C ≤ 109
) and the sum of the maximum number of hits for all characters will
not be more than 1,000.
Output
For each test case, print a single line which contains 2 space separated integers, the ?rst is the minimum
cost for the hits used to kill the monster and the second is the damage incurred upon the monster. If
there is more than one way to kill the monster using the same minimum cost, select the one with the
least damage and if there is no way to kill the monster print ‘We are doomed!!’ (without the quotes).
Sample Input
2
33
2 3 4
3 1 2
4 3 2
1 7 1
3 4 2
51
3 3 1
4 3 2
2 3 3
3 1 4
5 2 3
Sample Output
19 33
We are doomed!!

貌似中途相遇法,时间2500ms

view code#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define iform "%I64d"
const int N = (1<<20)+10;
const ll INF = 1LL<<60;
ll _, L;
ll Min[N<<4],pos[N<<4], x[N<<1], xcnt;
ll d[100], c[100], cnt;
ll damage, cost;
struct node
{
    ll v, c;
    bool operator < (const node &o) const{
        return v>o.v;
    }
}one[N], two[N];
bool cmp(const node& a, const node &b)
{
    return a.c<b.c;
}
void calc(node o[], int n, ll d[], ll c[], int &cnt)
{
      cnt = 0;
      for(int i=0; i<n; i++)
      {
          int k = cnt;
          for(int j=0; j<k; j++)
          {
              if(o[j].v>=L) continue;
              o[cnt].v = o[j].v+d[i];
              o[cnt].c = o[j].c+c[i];
              if(o[cnt].v>=L)
              {
                  if(o[cnt].c<cost) cost = o[cnt].c, damage=o[cnt].v, cnt++;
                  else if(o[cnt].c==cost && damage>o[cnt].v) damage = o[cnt].v,cnt++;
              }
              else cnt++;
          }
          o[cnt].v = d[i];
          o[cnt].c = c[i];
          if(o[cnt].v>=L)
          {
              if(o[cnt].c<cost) cost = o[cnt].c, damage=o[cnt].v, cnt++;
              else if(o[cnt].c==cost && damage>o[cnt].v) damage = o[cnt].v,cnt++;
          }
          else cnt++;
      }
}
int ocnt, tcnt;

void solve()
{
    scanf(iform, &L);
    ll num, dam, cos;
    cnt = 0;
    for(int i=1; i<=5; i++)
    {
        scanf(iform iform iform, &num, &dam, &cos);
        ll k = 1;
        while(num)
        {
            ll t = min(k, num);
            d[cnt] = dam*t;
            c[cnt] = cos*t;
            cnt++;
            num -= t;
            k *= 2;
        }
    }
    xcnt = 0;damage = -1, cost = INF;
    ll n =cnt/2, m = cnt-n;
    calc(one, n, d, c, ocnt);
    calc(two, m, d+n, c+n, tcnt);
    sort(one, one+ocnt, cmp);
    sort(two, two+tcnt);
    int i=0, j=0;
    while(j<tcnt && two[j].v>=L) j++;
    for(; i<ocnt&&j<tcnt; i++)
    {
        if(one[i].v>=L) continue;
        else
        {
            while(j<tcnt && one[i].v+two[j].v>=L)
            {
                ll sumc = one[i].c+two[j].c;
                ll sumv = one[i].v+two[j].v;
                if(sumc<cost) damage=sumv,cost=sumc;
                else if(sumc==cost) damage=sumv;
                j++;
            }
        }
    }
    if(damage==-1) puts("We are doomed!!");
    else cout<<cost<<""<<damage<<endl;
}
int main()
{
//    freopen("in.txt", "r", stdin);
    cin>>_;
    while(_--) solve();
    return 0;
}

uva 6757 Cup of Cowards(中途相遇法,貌似),布布扣,bubuko.com

时间: 2024-10-07 06:00:01

uva 6757 Cup of Cowards(中途相遇法,貌似)的相关文章

UVA 1326 Jurassic Remains 中途相遇法

题目链接:点击打开链接 题意:给定n个字符串,选尽可能多的字符串使得每种字母出现的次数为偶数次 思路: 中途相遇法 import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedLi

uva1152 - 4 Values whose Sum is 0(枚举,中途相遇法)

用中途相遇法的思想来解题.分别枚举两边,和直接暴力枚举四个数组比可以降低时间复杂度.可是我不会写...看了紫书作者刘汝佳老师的代码,真是太美了!简单明了,就像看吕钦下的棋一样.我就模仿的写了一下: #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set>

POJ 1840 Eqs Hash + 中途相遇法

把等式分成两拨算用中途相遇法就好了. 不过要注意的是这里不能用map,会超时,要自己手写hash,我重载了[]操作符之后用起来和map差不多,很随意 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <qu

Codeforces Round #297 (Div. 2) E题. Anya and Cubes (中途相遇法)

题目地址:Anya and Cubes 比赛的时候居然没想起中途相遇法...这题也是属于想起来就很简单系列. 中途相遇法也叫折半搜索.就是处理前一半,把结果储存起来,再处理后一半,然后匹配前一半存储的结果. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib

HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))

Difference Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 62    Accepted Submission(s): 19 Problem Description Little Ruins is playing a number game, first he chooses two positive integers y an

【中途相遇法】【STL】BAPC2014 K Key to Knowledge

题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11674&courseid=0 题目大意: N个学生M道题(1<=N<=12,1<=M<=30),每道题只有正误两种选项(0 1),每个学生的答题情况和正确题数已知,求标准答案可能有多少种. 如果标准答案只有一种则输出标准答案,否则输出解的个数. 题目思路: [

J 中途相遇法,求和

---恢复内容开始--- J - 中途相遇法 Time Limit:9000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Description The SUM problem can be formulated as follows: given four lists A, B, C, D<tex2html_verbatim_mark> of integer values, compute

codeforces 525 E Anya and Cubes 中途相遇法

codeforces 525 E Anya and Cubes 中途相遇法 题意: 给出n个数a1,a2,...,an,要求从中选出一些数,可以把其中最多k个变成它自己的阶乘,然后选出的数求和,问最后和等于s的选法有多少种. 限制: 1 <= n <= 25; 0 <= k <= n; 1<= s <= 1e16; 1 <= ai <= 1e9 思路: 一般数据量20~30都会考虑中途相遇法,就是折半暴力. ps:用三进制暴力会比直接深搜多一个常数10,因为

Codeforces 31E TV Game 中途相遇法 状压dp

题目链接:点击打开链接 题意: 给定2*n长的数字. 把这个数字拆成2个长度为n的数字,且相对位置不变.使得拆后得到的2个数字的和最大. 输出一个方案. 显然是中途相遇法,先计算左半段,再计算右半段 分别状压左半段和右半段,注意左半段状压后要在末尾补上0. 代码估计哪里有小越界==,数组开大了一点才过..具体就不查了. #include<iostream> #include<stdio.h> #include<string.h> #include<string&g