题目:
代码:
int cmp(const void *a, const void *b){
return *(int*)a - *(int*)b;
}
int maxSatisfaction(int* satisfaction, int satisfactionSize){
//升序排序
qsort(satisfaction, satisfactionSize, 4, cmp);
int satisfactionSizeLog = satisfactionSize;
int sum = 0;
int result = 0;
//总体求和
while(satisfactionSizeLog--){
sum += satisfaction[satisfactionSizeLog];
}
//判断是否删去
for(int i = 1, j = 1; i <= satisfactionSize && j <= satisfactionSize; i++, j++){
sum -= satisfaction[i - 1];
while(satisfaction[i - 1] < 0 && (satisfaction[i - 1] * j * -1 - sum) > 0 ? 1 : 0){
i++;
//防止下标越界
if(!(i <= satisfactionSize)){
return 0;
}
sum -= satisfaction[i - 1];
}
result += satisfaction[i - 1] * j;
}
return result;
}
解题思路
从特殊到一般 如果都是正数 那么直接升序排列就行(satisfaction越大的在后面 乘对应时间也就越大)如果satisfaction列表有负数那么就要考虑删不删;删几个的问题 考虑删除任意负数ai 相当于加上A = (ai * time[i] * -1) 后面的菜全部提前 他们的time[]全部减一 即B = { a(i + 1) * time[i] + a(i + 2) * time[i + 1] + ... + a(n) * time[n - 1] } (time[n - 1]是因为减去的一个菜 若减去两个菜 就是time[n - 2]), 那么只要比较A - B 是否大于零 若大于零 则应该删去这个负数 此后的负数只要满足A - B都应该删去
贪心:删不删只跟后面的数字有关 和前面的无关 因此是只关心局部最优解 进而达到全局最优解。