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;
}
View Code

但是还有一种更简单的方法: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;
}
View Code
原文地址:https://www.cnblogs.com/heyuhhh/p/10294360.html