题目链接:http://codeforces.com/problemset/problem/1042/B
题目大意:意思很简单,有ABC三种维他命。然后给你一堆果汁,每瓶果汁包含一种或几种维他命。然后问:如果要补充三种维他命,至少花多少钱。如果不能补充三种维他命,则输出-1。
题解思路:其实我刚开始并没有觉得很简单,至少得什么二分之类的。随便打了一个暴力,三重循环,结果他给我过了。
其实三重循环是可以优化的,我们将三种不同的果汁三重循环一次,然后将两种果汁循环一次,然后将一种果汁循环一次。虽然复杂度没有降很多,但是时间不会那么捉急了。
其实也可以这样想:题目的情况太少了,我们甚至可以列举出维他命的组合方式,所以我们为什么不记录各种维他命组合方式的最小值呢,然后枚举可能的维他命组合方式。
题目代码:
三重循环的代码:
#include <bits/stdc++.h>
using namespace std;
const int MAX_INF=1e9+7;
int main()
{
int n,a[1005][4],x,mn=MAX_INF;
string s;
scanf("%d",&n);
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
scanf("%d",&x);cin>>s;
for(int j=0;j<s.length();j++)
a[i][s[j]-'A'+1]=x;
}
for(int i=0;i<n;i++){
if(!a[i][1])continue;
for(int j=0;j<n;j++){
if(!a[j][2])continue;
for(int k=0;k<n;k++){
if(!a[k][3])continue;
else {int res;
if(i==j){
if(i==k)res=a[i][1];
else res=a[i][1]+a[k][3];
}
else {
if(i==k){res=a[i][1]+a[j][2];}
else if(j==k){res=a[i][1]+a[k][3];}
else res=a[i][1]+a[j][2]+a[k][3];
}mn=min(res,mn);
}
}
}
}
printf("%d",mn==MAX_INF?-1:mn);
return 0;
}
暴力枚举:
#include <bits/stdc++.h>
using namespace std;
const int INF=1000000007;
int main(){
long long n,cost,a,b,c,ab,ac,bc,abc;
a=INF;b=INF;c=INF;ab=INF;bc=INF;ac=INF;abc=INF;
cin>>n;string s;
for(int i=0;i<n;i++){
cin>>cost>>s;
if(s=="A"){a=min(a,cost);}
if(s=="B"){b=min(b,cost);}
if(s=="C"){c=min(c,cost);}
if(s=="AB"||s=="BA"){ab=min(ab,cost);}
if(s=="AC"||s=="CA"){ac=min(ac,cost);}
if(s=="BC"||s=="CB"){bc=min(bc,cost);}
if(s.length()>2)abc=min(abc,cost);
}
long long ans=INF;
ans=min(ans,a+b+c);
ans=min(ans,a+bc);
ans=min(ans,b+ac);
ans=min(ans,c+ab);
ans=min(ans,ab+bc);
ans=min(ans,ac+bc);
ans=min(ans,ab+ac);
ans=min(ans,abc);
if(ans==INF)cout<<-1;
else cout<<ans;
return 0;
}
不管了,智商有限。就能想到暴力了。还有其他的方法,读者可以百度。将三重循环优化的代码就不贴了。