Codeforces Round #510 (Div. 2) B. Vitamins

B. Vitamins

题目链接:https://codeforces.com/contest/1042/problem/B

题意:

给出几种药,没种可能包含一种或多种(最多三种)维生素,现在问要吃到这三种维生素买药最少花费是多少。

题解:

嗯...可以直接暴力:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+5;
int n;
int c[N];
char s[N][5];
int mn[10];
int main(){
    scanf("%d",&n);
    for(int i=1;i<9;i++) mn[i]=5000000;
    string s1="BA",s2="AB",s3="AC",s4="CA";
    for(int i=1;i<=n;i++){
        scanf("%d %s",&c[i],s[i]);
        if(strlen(s[i])==1){
            if(s[i][0]==‘A‘) mn[1]=min(mn[1],c[i]);
            else if(s[i][0]==‘B‘) mn[2]=min(mn[2],c[i]);
            else mn[3]=min(mn[3],c[i]);
        }else if(strlen(s[i])==2){
            if(s[i]==s1 || s[i]==s2)
                mn[4]=min(mn[4],c[i]);
            else if(s[i]==s3 || s[i]==s4){
                mn[5]=min(mn[5],c[i]);
            }else{
                mn[6]=min(mn[6],c[i]);
            }
        }else{
            mn[7]=min(mn[7],c[i]);
        }
    }
    int ans = 400000;
    ans=min(ans,mn[1]+mn[2]+mn[3]);
    ans=min(ans,mn[1]+mn[6]);
    ans=min(ans,mn[2]+mn[5]);
    ans=min(ans,mn[3]+mn[4]);
    for(int i=4;i<=7;i++){
        for(int j=4;j<=7;j++){
            if(i==j) continue ;
            ans=min(ans,mn[i]+mn[j]);
        }
    }
    ans=min(ans,mn[7]);
    if(ans==400000) cout<<"-1";
    else cout<<ans;
    return 0;
}

但是还有一种更简单的方法:dp,利用位运算来做。

代码如下:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1005;
int dp[10],a[N];
char s[N];
int n;
int main(){
    scanf("%d",&n);
    memset(dp,INF,sizeof(dp));
    dp[0]=0;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        scanf("%s",s);
        int len = strlen(s),x=0;
        for(int j=0;j<len;j++) x|=(1<<(s[j]-‘A‘));
        for(int j=0;j<8;j++) dp[x|j]=min(dp[x|j],dp[j]+a[i]);
    }
    if(dp[7]==INF) cout<<-1;
    else cout<<dp[7];
    return 0;
}

原文地址:https://www.cnblogs.com/heyuhhh/p/10294360.html

时间: 2024-10-12 20:23:00

Codeforces Round #510 (Div. 2) B. Vitamins的相关文章

Codeforces Round #510 (Div. 2) D. Petya and Array (权值线段树)

题目地址:http://codeforces.com/contest/1042/problem/D 题意:给你n个数,问有多少个区间的和的值小于t 分析:区间和问题,常常用到前缀和来进行预处理,所以先预处理出前缀和数组sum sum[i]代表前i个数的和,那么sum[i]的贡献就是,  当i<k<=n时,存在多少个k,使sum[k]<t+sum[i] 也就是求在[i+1,n]中,小于t+sum[i]的数有多少. 所以我们可以类比于询问一个数是区间第几大的方法,使用权值线段树来解决,这里因

Codeforces Round #510 (Div. 2) A&amp;B By cellur925

第一次CF祭== 由于太菜了只做了前两题== 因为在第一题上耗费时间太多了,我还是太菜了==. A. Benches time limit per test 1 second memory limit per test 256 megabytes There are nn benches in the Berland Central park. It is known that aiai people are currently sitting on the ii-th bench. Anoth

Codeforces Round #510 (Div. 2)(A)

传送门:Problem A https://www.cnblogs.com/violet-acmer/p/9682082.html 题意: 公园里有n个沙滩,a[i]表示第i个沙滩初始人数,现有m个人可以到任意沙滩,在这m个人全部到达任意沙滩后,求沙滩最多人数的最大值和最小值 例如: 假设有n=5,m=3 a[i] = :1 2 3 4 5 沙滩人数最大化便是这m个人全到第5个沙滩上,a[5]=8,当前所有沙滩的最大值为8 使沙滩人数最大值尽量最小化,第一个人可以来到第一个沙滩,第二个人来到第二

Codeforces Round #536 (Div. 2)

目录 Codeforces Round #536 (Div. 2) A 题目大意 题解 卡点 C++ Code: B 题目大意 题解 卡点 C++ Code: C 题目大意 题解 卡点 C++ Code: D 题目大意 题解 卡点 C++ Code: E 题目大意 题解 卡点 C++ Code: F 题目大意 题解 卡点 C++ Code: Codeforces Round #536 (Div. 2) A 题目大意 给你一个\(n\times n(n\leqslant500)\)的矩阵,只包含.

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除