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