您的位置:首页 > 其它

《算法竞赛-训练指南》第一章-1.16_LA 3177

2013-07-19 21:58 363 查看
这道题目很有意思。但是我就是错的非常离谱,就差拿着题解一句话一句话的去对照了,不,其实我已经对照了的。

首先说一下这个题目的意思,就是说有N个塔防的士兵,他们分别相邻,1和2和N相邻,2和1和3相邻。现在每个塔防的士兵要奖品,问题是你发的奖品使得每个相邻的士兵不具有相同的奖品。

这个刚开始一看,没思路,是一道非常难的题目。

看了题解,也就懂了。自己的智商不高,怪不了别人那。你可以这样的理解题意,其实刚开始的时候自己都已经推导出了部分,但是因为太麻烦也给放弃了,在真正比赛中,还是希望自己能够分类讨论,细心的研究最少半个小时以上。这个也是分类讨论的,但是你讨论的前提也是要得知道怎么样才能得到最优的分配。比如这道题目,作者就给出了很好的最优分配,就是两边的士兵尽量要一边拿尽量小的,而另一边拿尽量大的。这样才能得到最优,当偶数的时候,直接就是相邻两个数最大的和情况是最优的。而当是奇数的时候,发现,这个时候的规律是不满足的,但是不要着急,我们知道了答案的范围,无非是大于2个数的和小于三个数的最大和。而且相差的又不很大,那么随便一二分答案,就能出来结果了。但是,别着急,还有重要的你没有解决,那就是怎么样把自己的思想转化成程序实现,我想就算我知道了这个思路,也实现不了这个程序,因为,你根本就不能讲你的思想通过数据结构,算法转化成程序,这就是自己程序设计能力不高的原因。

而题目中是,分别找去了两个数组,数组的值代表了你所取的奖励编号的个数,这个为什么可以这样表示?是因为你每次都是尽量取左边,尽量取右边,不是胡乱的取,所以我的个数就能唯一代表我取的,虽然具体是几号不知道,但是题中也没有让求。(让求我们也可以推出来!!!就是弄个扫一遍数组的值就可以实现)。

好了,就说这么多吧。很有价值,但是还是看自己能不能好好的利用吧!

贴出代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>

using namespace std;

const int MAXN = 100000 + 11;

int A[MAXN];

int L[MAXN];

int R[MAXN];

int N;

int max(int a, int b)
{
return a > b ? a : b;
}

bool check(int key)
{
int x = A[1]; // 这代表着将礼物分成两片,第一片是A[1]为左边,
int y = key - A[1]; //第二片为key - A[1]为右边;
L[1] = x;
R[1] = 0;
for (int i = 2; i <= N; i++)
{
if (i % 2 == 0) //如果是偶数的情况下,极力的向左靠近
{
L[i] = min(x - L[i - 1], A[i]);
R[i] = A[i] - L[i];
}
else //如果是奇数的情况下,极力的向右靠近
{
R[i] = min(y - R[i - 1], A[i]);
L[i] = A[i] - R[i];
}
}
return L
== 0;
}

int main()
{
while (scanf("%d", &N) != EOF)
{
if (N == 0)
{
break;
}
for (int i = 1; i <= N; i++)
{
scanf("%d", &A[i]);
}
if (N == 1)
{
printf("%d\n", A[1]);
continue;
}
int MAX1 = -1;
int MAX2 = -1;
A[N + 1] = A[1];
for (int i = 1; i <= N; i++)
{
MAX1 = max(MAX1, A[i] + A[i + 1]);
}
for (int i = 1; i < N - 1; i++)
{
MAX2 = max(MAX2, A[i] + A[i + 1] + A[i + 2]);
// MAX2 = max(MAX2, A[i] * 3);
}

if (N % 2 == 0) //偶数的情况较为简单.
{
printf("%d\n", MAX1);
}

else
{
int left = MAX1;
int right = MAX2;
while (left < right) // 找最小值
{
int mid = left + (right - left) / 2;
if (check(mid))
{
right = mid;
}
else
{
left = mid + 1;
}
}
printf("%d\n", right);
}
}
// system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: