Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

读题不易啊,没理解或没思路的可以来看看

Posted by 2012339930038 at 2013-09-10 17:25:14 on Problem 1649
题意:已经有n个价格,按照一定的顺序排列好;
对于任意一个买东西的人,可以从两头分别去购买,可以看1个也可以看到第n个,然后选取理他最近的最便宜的一个;
对于k属于[1,n],给出走k步的概率bk,总和为100;(也就是输入的第三行)
现在要在加一个价格,选定放的位置和价格使得获利的期望最大;
输出位置和价格
对于位置,不能放首尾,如果获利最大的多项,优先选取位置靠前并且价格偏低的一个;
思路:对于价格只可能在n个价格中的最小值-1到最大值之间,也就是说最优解只可能产生于price[i]和price[i]-1之间,想想为什么。
之后就枚举位置和价格,一个二重循环搞定。
附代码
#include <cstdio>
#include <set>
std::set<int>s;
#define M 110
int price[M],bk[M],n,t[M];
int profit(int pos,int p){
	for(int i=1;i<=pos;i++)
		t[i]=price[i];
	t[pos+1]=p;
	for(int i=pos+1;i<=n;i++)
		t[i+1]=price[i];
	bool flag=true;
	int tot=0;
	for(int i=1;i<=pos;i++)//from left
		if(t[i]<p)flag=false;
	if(flag){
		tot+=bk[pos+1];
		for(int i=pos+2;i<=n;i++){
			if(t[i]<=p)break;
			tot+=bk[i];
		}
	}
	flag=true;
	for(int i=n+1;i>pos;i--)//from right
		if(t[i]<p)flag=false;
	if(flag){
		tot+=bk[n+1-pos];
		for(int i=pos;i>1;i--){
			if(t[i]<=p)break;
			tot+=bk[n-i+2];
		}
	}
	return p*tot;
}
int main(void){
	while(~scanf("%d",&n)){
		s.clear();
		for(int i=1;i<=n;i++){
			scanf("%d",&price[i]);
			s.insert(price[i]);
			s.insert(price[i]-1);
		}
		for(int i=1;i<=n;i++)
			scanf("%d",&bk[i]);
		int num=0,plf,ans=-99999;
		for(int i=1;i<n;i++)
			for(std::set<int>::iterator j=s.begin();j!=s.end();j++){
				int temp=profit(i,*j);
				if(temp>ans)
					ans=temp,num=i,plf=*j;
			}
		printf("%d %d\n",num,plf);
	}
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator