地址:http://codeforces.com/contest/1042/problem/B
他的情况只有A,B,C,AB,BC,AC,ABC七种,可以先将n个果汁进行两两组合更新七种情况的值,然后在七种两辆组合更新,这是比较暴力的解法
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 1005;
int change(string s)
{
sort(s.begin(),s.end());
if(s == "A") return 1;
if(s == "B") return 2;
if(s == "C") return 4;
if(s == "AB") return 3;
if(s == "BC") return 6;
if(s == "AC") return 5;
if(s == "ABC") return 7;
}
int a[15];
int b[N];
int c[N];
int main()
{
int n;
scanf("%d",&n);
memset(a,inf,sizeof(a));
for(int i = 0;i < n;++i)
{
string s;
cin >> b[i] >> s;
int x = change(s);
a[x] = min(a[x],b[i]);
c[i] = x;
}
for(int i = 0;i < n;++i)
{
for(int j = i + 1;j < n;++j)
{
int x = c[i] | c[j];
a[x] = min(a[x],b[i] + b[j]);
}
}
for(int i = 1;i <= 7;++i)
{
for(int j = i + 1;j <= 7;++j)
{
int x = i | j;
a[x] = min(a[x],a[i] + a[j]);
}
}
if(a[7] == inf){
printf("-1\n");
}else{
printf("%d\n",a[7]);
}
return 0;
}
接下来是状压dp
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
char s[15];
int a[15];
int main()
{
int n;
scanf("%d",&n);
memset(a,inf,sizeof(a));
for(int i = 0;i < n;++i)
{
int m;
scanf("%d %s",&m,s);
int len = strlen(s);
int ans = 0;
for(int j = 0;j < len;++j)
{
switch(s[j]){
case 'A':ans |= 1;break;
case 'B':ans |= 2;break;
case 'C':ans |= 4;break;
}
}
a[ans] = min(a[ans],m);
for(int j = 1;j <= 7;++j)
{
if(a[j] + m < a[(ans | j)]){
a[(ans | j)] = a[j] + m;
}
}
}
if(a[7] == inf){
printf("-1\n");
}else{
printf("%d\n",a[7]);
}
return 0;
}