讨论 / 命题人对该问题的补充说明
libojie 2012-02-12 22:58:00
点我顶贴 收藏 删除
最大值MAX就是前M个数中的最大值。因为你已经看了前M个数而并未选择,所以你知道这M个数中的最大值MAX,以后再根据MAX进行选择。

这个题开始未被收录,是因为太古怪了。其实,这个题考察了选手对rand()随机函数的应用。

用数学的正统方法,很难得到正确结果,效率也不高。命题人采用的办法是随机生成若干组(10000以上,同时避免超时)随机数,每组N个,针对不同的M进行试验,即可选出最大值。

在本机上调试时,会发现随着N的增大,最佳的M变化不是很大,N<=10000时,M<=10,这可能出乎多数人的意料。并且最佳的M随N的增大而增大,是增函数。于是正式提交程序时,这需对较小的M进行试验,提高时间效率,不会超时。

这个题型由于涉及随机化方法,在NOIP中尚未出现过,仅当作对未来题型的预测。

#1 binarie@2008-10-04 21:05:00
回复 删除
up -.-
#2 lychees@2008-10-04 22:40:00
回复 删除
...我懂这题的意思了~~
#3 libojie@2008-11-05 00:52:00
回复 删除
这道题我表达不清楚。

简单的说,就是枚举出所有可能的情况,例如限定随机数的范围是1-100,数列的长度是n,则共可能有100^n种可能的状态(完全随机,数允许重复)。首先给定参数m,在这100^n种数列中,分别按照规定的方法模拟,计算取到的数;再对这100^n个取到的数取平均值,就是要求的“加权平均值”。对每个可能的m都计算一次,再取使得“加权平均值”最大的m。

#4 怡红公子@2012-02-12 22:58:00
回复 删除
回复 板凳lychees 的帖子

你能告诉我下面两个程序有什么差别导致答案不对吗?

#include<iostream>

using namespace std;

int main()

{

int n,m,i,j,k,ans=0,max,tot,t,num=1000;

cin>>n;

if(n==1) {cout<<0<<endl;return 0;}

if(n==1000)

num=1500;

for(i=1;i<=11;i++)

{

tot=0;

for(j=1;j<=num;j++)

{

max=0;

for(k=1;k<=i;k++) //差别,细节

{

t=rand()%100;

if(t>max) max=t;

}

for(k=i+1;k<=n;k++)

{

t=rand()%100;

if(t>max) break;

}

tot+=t;

}

if(tot>ans)

{

ans=tot;

m=i;

}

}

cout<<m<<endl;

system("pause");

return 0;

}

#include<iostream>

using namespace std;

int main()

{

int n,m,i,j,k,ans=0,max,tot,t,num=1000;

cin>>n;

if(n==1) {cout<<0<<endl;return 0;}

if(n==1000)

num=1500;

for(i=1;i<=11;i++)

{

tot=0;

for(j=1;j<=num;j++)

{

max=0;

for(k=1;k<i;k++) //差别,细节

{

t=rand()%100;

if(t>max) max=t;

}

for(k=i;k<=n;k++)

{

t=rand()%100;

if(t>max) break;

}

tot+=t;

}

if(tot>ans)

{

ans=tot;

m=i;

}

}

cout<<m-1<<endl;

system("pause");

return 0;

}

查看更多回复
提交回复