bzoj3874 [ AHOI2014 ] -- 爬山算法

2018-06-17 22:57:44来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

不知道为什么,用模拟退火就WA了。。。

显然如果知道了总共购买几次,就可以贪心地求出答案。那么套个爬山就行了。

 

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cstdlib>
 7 #include<cmath>
 8 using namespace std;
 9 #define N 210
10 #define ll long long
11 struct Node{
12     ll p,s;
13 }a[N],A[N],b[N];
14 ll m,Ans,x,y,C,f,N2;
15 int i,j,k,n,Cnt,Tot;
16 inline ll _Min(ll x,ll y){return x<y?x:y;}
17 inline bool Cmp1(Node a,Node b){
18     return a.s>b.s||(a.s==b.s&&a.p<b.p);
19 }
20 inline bool Cmp2(Node a,Node b){
21     return a.p<b.p||(a.p==b.p&&a.s>b.s);
22 }
23 inline double Getrand(){
24     return rand()%1000/1000.0;
25 }
26 inline ll Calc(ll x){
27     if(x==0)return 0;
28     ll S=m-x*f,A=0,d=0,y;
29     for(int i=1;i<=n;i++){
30         y=_Min(S/a[i].p/x,a[i].s-d+1);
31         S-=x*y*a[i].p;
32         d+=y;A+=x*y;
33         if(d<=a[i].s){
34             y=S/a[i].p;
35             A+=y;
36             break;
37         }
38     }
39     if(A>Ans)Ans=A;
40     return A;
41 }
42 inline void HC(double T){
43     for(x=1,Ans=Calc(x);T>1;T*=0.9){
44         y=x+(ll)(T*(Getrand()*2-1));
45         if(y<1)continue;
46         C=Calc(y)-Calc(x);
47         if(C>0)x=y;
48     }
49 }
50 int main()
51 {
52     srand(1000000007);
53     scanf("%lld%lld%d",&m,&f,&n);
54     for(i=1;i<=n;i++)scanf("%lld%lld",&A[i].p,&A[i].s);
55     sort(A+1,A+n+1,Cmp1);
56     b[Cnt=1]=A[1];
57     for(i=2;i<=n;i++)if(A[i].s!=A[i-1].s)b[++Cnt]=A[i];
58     sort(b+1,b+Cnt+1,Cmp2);
59     a[Tot=1]=b[1];
60     for(i=2;i<=Cnt;i++)if(b[i].p!=b[i-1].p)a[++Tot]=b[i];
61     n=Tot;
62     HC(m/(double)f);
63     printf("%lld",Ans);
64     return 0;
65 }
bzoj3874

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:1014. 写评语

下一篇:1012. 变换密码