Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
读题不易啊,没理解或没思路的可以来看看题意:已经有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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator