这道题我很快就写出来了, 但是一直WA, 然后发现是精度, 这坑了我一个小时……
(1)贪心。每次就尽量分数高, 可以保证最后分数最高
(2)神tm精度问题。记住判断大于小于和等于的时候要用EPS(1e-6)
a == b fabs(a-b) < EPS
a != b fabs(a-b) > EPS
a < b a + EPS < b
a <= b a - EPS < b
a > b b + EPS < a
a >= b b - EPS < a
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;const int MAXN = 21234;
const double EPS = 1e-6;
vector<double> score[MAXN];
int num[MAXN], n;void add(int i, double x, double y, double z)
{score[i].clear();score[i].push_back(0);score[i].push_back(x); score[i].push_back(y);score[i].push_back(z); score[i].push_back(x+y);score[i].push_back(y+z); score[i].push_back(x+z);score[i].push_back(x+z+y);sort(score[i].begin(), score[i].end());
}int main()
{int kase = 0;while(~scanf("%d", &n) && n){REP(i, 0, n){double x, y, z;scanf("%lf%lf%lf", &x, &y, &z);add(i, x, y, z);}REP(i, 0, n) scanf("%d", &num[i]), num[i]--;double ans = 2e9; bool ok = true;REP(i, 0, n){int x = num[i], pos = 0;while(pos < score[x].size() && score[x][pos] + EPS < ans) pos++;if((i == 0 || num[i] > num[i-1]) && pos < score[x].size() && fabs(score[x][pos] - ans ) < EPS) continue;if(pos - 1 < 0) { ok = false; break; }ans = score[x][pos-1];}if(ok) printf("Case %d: %.2lf\n", ++kase, ans);else printf("Case %d: No solution\n", ++kase);}return 0;
}