贪心题,只要每一步都保证B的费用小于等于A的费用,则一直用B方案,否则用A方案结束,唯一值得注意的是在B方案减半时不能使N的值小于M的值(题目中有要求)。
代码如下:
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> using namespace std; struct agency { int A, B, V; char name[20]; } gen[102]; int cmp(const void *a, const void *b) { agency *aa = (agency*)a; agency *bb = (agency*)b; if(aa->V != bb->V) return aa->V - bb->V; return strcmp(aa->name, bb->name); } int main() { #ifdef test freopen("in.txt", "r", stdin); #endif int t; char str[50]; scanf("%d", &t); for(int k = 1; k <= t; k++) { int N, M, num; scanf("%d%d%d", &N, &M, &num); for(int i = 0; i < num; i++) { scanf("%s", str); sscanf(str, "%[^:]:%d,%d",gen[i].name, &gen[i].A, &gen[i].B); } for(int i = 0; i < num; i++) { int tem_a = 0, tem_b = 0, n = N; while(n / 2 >= M && gen[i].A * (n / 2) > gen[i].B) // 实际为 gen[i].A * (n-(n/2)),保证每一步A的费用都大于B的费用 { n /= 2; ++tem_b; } tem_a = n - M; gen[i].V = tem_b * gen[i].B + tem_a * gen[i].A; } qsort(gen, num, sizeof(gen[0]), cmp); printf("Case %d\n", k); for(int i = 0; i < num; i++) printf("%s %d\n", gen[i].name, gen[i].V); } return 0; }