贪心思路 : 循环从石子数量最多的两堆取石子,直到有两堆以上(含两堆)空石子,维护取子次数,即是答案。贪心的正确性,暂无数学证明。直觉来看,这么做是对的。
CPP
class Solution {
public:
int maximumScore(int a, int b, int c) {
int f[3] = {a,b,c};
sort(f,f+3);
int ans = 0;
while(f[0]||f[1]){
ans++;
f[1]--,f[2]--;
sort(f,f+3);
}
return ans;
}
};
C
int cmp(const void *a,const void *b){
return *(int*)a-*(int*)b;
}
int maximumScore(int a, int b, int c){
int f[3] = {a,b,c};
qsort(f,3,sizeof(int),cmp);
int ans = 0;
while(f[0]||f[1]){
ans++;
f[1]--,f[2]--;
qsort(f,3,sizeof(int),cmp);
}
return ans;
}
将 a , b , c a,b,c a,b,c 存入数组 f f f 按升序排序。如果 f [ 0 ] + f [ 1 ] < = f [ 2 ] f[0]+f[1]<=f[2] f[0]+f[1]<=f[2] ,根据贪心思路,每次取最大两堆的石子,就是循环从 f [ 2 ] f[2] f[2] 和 m a x ( f [ 0 ] , f [ 1 ] ) max(f[0],f[1]) max(f[0],f[1]) 取石子。取石子的次数 = f [ 0 ] + f [ 1 ] =f[0]+f[1] =f[0]+f[1]
如果 f [ 0 ] + f [ 1 ] > f [ 2 ] f[0]+f[1]>f[2] f[0]+f[1]>f[2] ,可以想象,这种情况一定可以最大限度的取完所有石子——①三堆都取完 ②某一堆剩 1 1 1 个石子,其他两堆取完。根据贪心思路,每次取最大两堆,它的终止条件就是①或②。取石子的次数,只和终止状态下,三堆剩余的石子数有关。我们可以随便取,只要达到①或②的终止状态,就是最优解法。
考虑先从 f [ 2 ] f[2] f[2] 和 m a x ( f [ 0 ] , f [ 1 ] ) max(f[0],f[1]) max(f[0],f[1]) 取石子, f [ 2 ] f[2] f[2] 一定会被取完,因为 f [ 0 ] + f [ 1 ] > f [ 2 ] f[0]+f[1]>f[2] f[0]+f[1]>f[2] 。取完 f [ 2 ] f[2] f[2] 时, f [ 0 ] f[0] f[0] 和 f [ 1 ] f[1] f[1] 的差值不大于 1 1 1 ,接着从 f [ 0 ] f[0] f[0] 和 f [ 1 ] f[1] f[1] 中取石子,最后也能达到三堆都取完或者某一堆剩 1 1 1 个石子,其他两堆取完的状态 。取石子的次数 = ( f [ 0 ] + f [ 1 ] + f [ 2 ] ) ÷ 2 =(f[0]+f[1]+f[2])\div 2 =(f[0]+f[1]+f[2])÷2
CPP
class Solution {
public:
int maximumScore(int a, int b, int c) {
int f[3] = {a,b,c};
sort(f,f+3);
if(f[0]+f[1]<=f[2]) return f[0] + f[1];
return f[0]+f[1]+f[2]>>1;
}
};
C
int cmp(const void *a,const void *b){
return *(int*)a-*(int*)b;
}
int maximumScore(int a, int b, int c){
int f[3] = {a,b,c};
qsort(f,3,sizeof(int),cmp);
if(f[0]+f[1]<=f[2]) return f[0] + f[1];
return f[0]+f[1]+f[2]>>1;
}