石子游戏

36 篇文章 0 订阅
1 篇文章 0 订阅

/*
问题描述
  石子游戏的规则如下:
  地上有n堆石子,每次操作可选取两堆石子(石子个数分别为x和y)并将它们合并,
操作的得分记为(x+1)×(y+1),对地上的石子堆进行操作直到只剩下一堆石子时停止游戏。
  请问在整个游戏过程中操作的总得分的最大值是多少?
输入格式
  输入数据的第一行为整数n,表示地上的石子堆数;第二行至第n+1行是每堆石子的个数。
输出格式
  程序输出一行,为游戏总得分的最大值。
样例输入
10
5105
19400
27309
19892
27814
25129
19272
12517
25419
4053
样例输出
15212676150
15212676150
数据规模和约定
  1≤n≤1000,1≤一堆中石子数≤50000
*/
使用贪心
先用归纳法证明一下正确性 发现可用long long 就足够了
好比一个具体的数列 1 2 3
使其一般化 即设数列 a1 a2 a3 ,
其中 a1 是 1 2 3 当中的任意一个数 a2 是 1 2 3 中除了a1的任意的一个数 那么a3就是剩下的最后的一个数
这样我们即使从前往后的堆 也能求出一个通用的 求和公式:
sum = a1(a3+a2+2) + a2(a3+2)+ a3+2
当 有四个数的时候
a1 a2 a3 a4
sum = a1(a4+a3+a2+3) + a2(a4+a3+3) + a3(a4+2) + a4+3
不知道有没有发现什么规律~_ ~
sum_n = a1(an +…a2+n-1) + a2(an+an-1 +…+a3+n-1) + …+ an + n-1
用数学归纳法很好证的
也就是a1出现的次数最多 其次是 a2 。。。。 an 于是那么肯定就是
a1是最大的 其次是 a2 最后是 an

于是就可以做出来啦 =_+

#include <stdio.h>
#include <stdlib.h>
void input(int ,int[]);
int cmp(const void*,const void*);
long long q_zhi(int,int[]);
int main(void) 
{
	int n;
	scanf("%d",&n);
	int sz[n];
	input(n,sz);
	qsort(sz,n,sizeof(int),cmp);
	printf("%lld",q_zhi(n,sz));
	return 0;
}
int cmp(const void*a,const void*b)
{
	return *(int*)b - *(int*)a;
}
long long q_zhi(int n,int sz[])
{
	int i;
	long long ans = 0;
	for(i = 0;i < n-1;i++)
	{
		ans += (long long)(sz[i]+1)*(sz[i+1]+1);
		sz[i+1] += sz[i];
	}
	return ans;
}

void input(int n,int sz[])
{
	int i;
	for(i = 0;i < n;i++)
	{
		scanf("%d",sz+i);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值