zoukankan      html  css  js  c++  java
  • 淘淘与蓝蓝之电电⿏⼤战御坂美琴

    题目大意

    给出 (n,W,ct) 表示有 (ct)(n) 的约数,每个大小为 (d_i) 且有 (a_i) 个相同的
    现将其放入 (W) 大的空间中,问最多能装满多少空间
    对于 (100%) 的数据,(1leq nleq 10^4,1leq a_i,Wleq 10^{15})

    分析

    显然想到背包
    然后发现 (W) 太可怕,果断舍弃
    其实,可以考虑随机化贪心
    我们让这几个数排成一个序列,从头到尾能取多少就取多少
    然后做很多次
    与我们我们能拿到 (85) 分的好成绩(数据太废)
    或者同理模拟退火,同样可以拿到 (85) 分的好成绩(数据太废)

    于是剩下 (15) 分怎么搞都搞不到
    但我们不能放弃
    于是在隔壁大神 (LZC) 的指导下
    我们可以将两者结合起来
    首先随机化贪心,同上,并记录每个数选了多少个
    然后模拟退火
    随机 (x,y,z)
    表示第 (x) 个数少取 (z) 个,剩余空间给第 (y) 个数尽量多取
    于是非常高兴地 (A)

    (Code)

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<ctime>
    #define LL long long 
    using namespace std;
    
    const int N = 64;
    int n , ct;
    LL W , ans = 0 , cur; 
    struct node{
    	int d; LL a , c;
    }s[N] , tmp[N];
    
    LL getans()
    {
    	LL w = W;
    	for(register int i = 1; i <= ct; i++)
    	{
    		if (w <= 0) break;
    		s[i].c = min(s[i].a , w / s[i].d);
    		w -= s[i].c * s[i].d;
    	}
    	return W - w;
    }
    void RG()
    {
    	for(register int i = 1; i <= ct; i++) tmp[i] = s[i];
    	random_shuffle(s + 1 , s + ct + 1);
    	LL c = getans();
    	if (c > ans) ans = cur = c;
    	else for(register int i = 1; i <= ct; i++) s[i] = tmp[i];
    }
    void SA()
    {
    	srand(time(NULL));
    	double T = 5000 , delta = 0.998;
    	LL x , y , z , v , cx , cy;
    	while (T > 1e-14)
    	{
    		x = (LL)(rand() * T) % ct + 1;
    		y = (LL)(rand() * T) % ct + 1;
    		z = (LL)(rand() * T) % (s[x].c + 1);
    		cx = s[x].c , cy = s[y].c , v = cur;
    		s[x].c -= z , v -= z * s[x].d;
    		z = min(s[y].a - s[y].c , (W - v) / s[y].d);
    		s[y].c += z , v += z * s[y].d;
    		if (v > ans) ans = cur = v;
    		else if (exp((v - ans) / T) * RAND_MAX > rand()) cur = v;
    		else s[x].c = cx , s[y].c = cy;
    		T *= delta;
    	}
    }
    
    int main()
    {
    	freopen("dedenneVSbilibili.in" , "r" , stdin);
    	freopen("dedenneVSbilibili.out" , "w" , stdout);
    	scanf("%d%lld%d" , &n , &W , &ct);
    	for(register int i = 1; i <= ct; i++) scanf("%d" , &s[i].d);
    	for(register int i = 1; i <= ct; i++) scanf("%lld" , &s[i].a);
    	for(register int i = 0; i < 10; i++) RG();
    	for(register int i = 0; i < 10; i++) SA();
    	printf("%lld
    " , ans);
    }
    
  • 相关阅读:
    H5新增——html概述
    H5新增———html5概述
    ASP.NET Web API Demo OwinSelfHost 自宿主 Swagger Swashbuckle 在线文档
    如何写个死循环,既不独占线程,又不阻塞UI线程?
    C# 扩展TaskScheduler实现独立线程池,支持多任务批量处理,互不干扰,无缝兼容Task
    C# async await 异步执行方法封装 替代 BackgroundWorker
    巨坑!
    C# .NET Socket SocketHelper 高性能 5000客户端 异步接收数据
    一个简单的例子看明白 async await Task
    一个非常轻量级的 Web API Demo
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/14035148.html
Copyright © 2011-2022 走看看