大家帮看一下这个算法优化的问题(附原题)

yanxiangtianji 2009-04-04 11:20:38
[Quote] Problem H -- 篮子中的苹果
Time Limit:1000ms Memory Limit:65535KB

--------------------------------------------------------------------------------

Description
XJTU苹果公司每天生产了n篮数量可能不相同的苹果,为了使对外销售的每篮苹果数量一样,他们首先决定将部分(也可以是全部或者没有)篮子里面的苹果全部分给员工享用,如果剩下的各篮苹果数量还不是完全相同,他们再考虑将每篮中的部分(也可以是全部或没有)苹果分给员工的家属享用,现在的问题是如何使对外销售的苹果数量最多呢?公司想请参加XJTUCPC'2008的你来解决这一问题。
Input
第一行包含一个整数n(1 <= n <= 50)。下面有n行,每一行有一个整数Wi(1 <= Wi <= 1000),表示第i个篮子中的苹果数目。
Output
仅一行,输出公司最多能对外销售的苹果数。
Sample Input
3
1
2
3
Sample Output
4
Hint
样例说明:有3篮子苹果,分别装有1,2,3个苹果。我们可以先将第1个篮子中的苹果全部给员工享用,然后从第3个篮子中拿出1个苹果给员工家属享用,这样就剩余2个都装有2个苹果的篮子。这样,最多可以对外销售4个苹果!
[/Quote]
这是小弟做的一道西交大OJ很靠前的题目,数学模型和算法都不很简单,对w[]排序后等价于求一个递增函数(递减也可以还简单一点 但是我是做的递增的)某点(x0,y0)处x=x0,y=y0与x轴及x=n所围图形的最大面积。
如图
分析:在数学模型的抽象中我把这个离散值的函数w(i)(图中黑框的高点)近似的按连续值函数分析W(i)(图中红线),显而易见这样的一个(严格)递增函数的面积必有且仅有一个极大值,且极值为最大值(我认为是这样,但要是算法本身没错那就应该是这个地方错的,不知道有没有人能构造出一个面积有多极大值且最大值不是第一个极大值的增函数)。
算法中:在函数递增的时候不断取较大的面积值(用t表示),一旦发现面积函数t(i)到达了递减阶段就停止。(特例说明:当w[i-1]==w[i]时,算出的t值会减小,因为W(i)不一定是严格的,所以用(w[i-1]==w[i])continue;语句忽略掉这些W'(i)=0的非严格点,使进入计算的函数为一个严格函数)
问题:该题共测试35组数据,上述算法在第15组数据时出错(如果西交的OJ没有问题的话)。由于该题规模不大,我做题时是穷举了i从0到n-1的所有面积值AC的。可是我想知道如果OJ没问题的话,我的优化到底是什么地方出了错。
代码:
#include <stdlib.h>
#include <stdio.h>
int cmp(const void*a,const void*b)
{
return (*(int*)a)-(*(int*)b);//升序排列
}
int main()
{
int n,w[100],i;
scanf("%d",&n); getchar();
for(i=0;i<n;i++)
{
scanf("%d",&w[i]); getchar();
}
qsort(w,n,sizeof(int),cmp);
int t;
for(t=w[0]*n,i=1;i<n;i++)
{
printf("%d ",t);
if(w[i-1]==w[i]) //变w为严格递增序列,意义在于保证下面的else if语句正确
continue;
else if(t<w[i]*(n-i)) //面积处于递增阶段
t=w[i]*(n-i);
/*
else if(t>w[i]*(n-i)) //优化,截去面积的递减阶段以提高效率(不加则为穷举)
break;
加上这句就是对不了*/
}
printf("\n%d\n",t);
return 0;
}
...全文
269 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanxiangtianji 2009-05-01
  • 打赏
  • 举报
回复
解释一下:
首先,有很多人指出我的结论是错的,没错它的确是错的,但是要说明我讨论的决大多数内容都是对了,而且极大和最大值都是存在的。

对于递增函数极值的问题其实至少要分为一下两个方面:(当然对以离散后的问题,这些连续模型的绝对结论是允许在一定范围内波动的)
1,二阶导小于零(允许波动):这是就是我最开始做的那一种情况,这时数据的增加是“相对”缓慢的,这时必有惟一极大值点,且单调,此时应用break语句以提高效率。(在本离散型问题中最大值是一定存在的,即使数据构造的牛B到没有极值)
2,二阶导大于零:这就想2楼举出的反例,在从y=10点(对连续型讨论)y''为正,而且还非常的大!次是其实也是有极值存在的,但这是极小值,囧。这种情况下我的程序立即就结束了,甚至都不等到极小值出现。

一般情况说明:对于一个足够大的构造的足够牛B的数据,它可以让二阶导反复变化,弄出好多个极大值和极小值来。综上:应该在这个时候使用continue,总体上取出所有极大值和递减段的起始点的值。

for(t=w[0]*n,i=1;i<n;i++)
{
if(w[i-1]==w[i])
continue;
else if(t<w[i]*(n-i))
t=w[i]*(n-i);
else if(t>w[i]*(n-i))
continue;
}
yanxiangtianji 2009-05-01
  • 打赏
  • 举报
回复
先向2楼的FancyMouse 道歉
上次看帖的时候不知怎么搞的我两次运行的结果一样的 就认为是你的反例是错的 今天看帖才终于发现是我错了 不好意思

谢谢 大家 我明白了

数学没学好啊
ffzhzhll 2009-04-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 fenix124 的回复:]
很简单啊。
先从小排序。
然后没到一个元素的时候,计算当前元素乘以它到末尾的元素个数,最大的即为结果。
[/Quote]

我想楼主出错的地方可能是:
“if(w[i-1]==w[i]) //变w为严格递增序列,意义在于保证下面的else if语句正确
continue;


w为严格递增序列,并不能保证t就严格递增。
FancyMouse 2009-04-06
  • 打赏
  • 举报
回复
乃不是说加了优化过不了么,这个就是加优化以后能cha的数据
删优化那个本来就是对的
xiaocha 2009-04-06
  • 打赏
  • 举报
回复
w排序后为递增序列, 但面积是否一定为递增序列呢?
你认为是, 实际上不是, 2楼已经举出了反例!
所以你的所谓优化是没有理据的, 是不成立!
fenix124 2009-04-06
  • 打赏
  • 举报
回复
很简单啊。
先从小排序。
然后没到一个元素的时候,计算当前元素乘以它到末尾的元素个数,最大的即为结果。
yanxiangtianji 2009-04-05
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 FancyMouse 的回复:]
会出现OJ有问题但是乃暴力能过的情况么?
----------------
3
9 10 1000

乃的那个什么递增递减的结论根本就是胡乱猜测
[/Quote]
你的那个数据我的代码跑没有问题啊 我的结论为什么不对 你能说明一下吗

上面的代码里有调试时看中间步骤的代码 结果显示有点乱 这个版本把它们去掉了
#include <stdlib.h>
#include <stdio.h>
int cmp(const void*a,const void*b)
{
return (*(int*)a)-(*(int*)b);//升序排列
}
int main()
{
int n,w[100],i;
scanf("%d",&n); getchar();
for(i=0;i<n;i++)
{
scanf("%d",&w[i]); getchar();
}
qsort(w,n,sizeof(int),cmp);
int t;
for(t=w[0]*n,i=1;i<n;i++)
{
// printf("%d ",t);
if(w[i-1]==w[i]) //变w为严格递增序列,意义在于保证下面的else if语句正确
continue;
else if(t<w[i]*(n-i)) //面积处于递增阶段
t=w[i]*(n-i);
/*
else if(t>w[i]*(n-i)) //优化,截去面积的递减阶段以提高效率(不加则为穷举)
break;
加上这句就是对不了*/
}
printf("%d\n",t);
return 0;
}
FancyMouse 2009-04-05
  • 打赏
  • 举报
回复
会出现OJ有问题但是乃暴力能过的情况么?
----------------
3
9 10 1000

乃的那个什么递增递减的结论根本就是胡乱猜测
binzhuliu 2009-04-05
  • 打赏
  • 举报
回复
不知道 哦 看不大懂 远

















---------------------------------------------------
2144
4399

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧