bzoj3874 [ AHOI2014 ] -- 爬山算法

不知道为什么,用模拟退火就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

 

转载于:https://www.cnblogs.com/gjghfd/p/6635991.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值