zoukankan      html  css  js  c++  java
  • P6187

    题面

    分析

    对于题面我们很容易发现,我们可以将n个数分成若干个长度相同的环。
    通过样例我们就可以发现,对于每个环,我会把最大的数都放在里面,我会在最大的边上放次大的和更次大的。

    如果你无法理解,我们看样例解释

    样例1中给出的是1 2 3 4 5 6这几个数

    k=1

    我们的方案是({3,1,2,4,6,5}),我们能看见,在最大的6左边放了5,右边放了4,然后再对于可连接的两个点5、4,5
    更大,我们把3放在5的边上,2放在4的边上,最后放下1

    k=2

    我们的方案是({3,6,1,4,2,5}),我们能把他分成两个环({6,4,5}),和({3,1,2}),可以看见,我们在第一个环中放了最大的几个,然后对于环内采用k=1时介绍的方法,然后解决完第一个环后用相同的方法解决第二个环

    然而考试的时候我就是这么写的,最后只拿到了80,有20分TLE了

    优化

    很容易发现,环的长度为(dfrac{n}{gcd(n,k)}) ,所以在整个程序中实际上会处理到的环的长度的数量并不是很多。

    考虑记忆化,因为如果两个问题中环的长度相同,显然答案也相同。我们只要记忆化一下即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    map<int, long long> record;
    
    int gcd(int a, int b)
    {
    	int temp;
    	while (b)
    	{
    		temp = b;
    		b = a % b;
    		a = temp;
    	}
    	return a;
    }(
    
    long long a[200005];
    
    int main()
    {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	for (int i = 0; i < n; i++)
    		scanf("%lld", a + i);
    	sort(a, a + n, greater<long long>()); //从大到小排序
    	for (int i = 0; i < m; i++)
    	{
    		int k;
    		scanf("%d", &k);
    		long long answer = 0;
    		if (k == 0) //特判,不然下面gcd会出错
    		{
    			for (int p = 0; p < n; p++)
    				answer += a[p] * a[p];
    			printf("%lld
    ", answer);
    			continue;
    		}
    		int ring = n / gcd(n, k); //环长
    		if (record[ring])		  //记忆化
    		{
    			printf("%lld
    ", record[ring]);
    			continue;
    		}
    		for (int p = 0; p < n; p += ring)
    		{ //对于每一个环,p记录每个环最开始的点的下标
    			for (int x = 0, tp = p + 1; x < (ring - 2) / 2; x++, tp += 2) //一半环
    				answer += a[tp] * a[tp + 2];
    			for (int x = 0, tp = p; x < (ring - 1) / 2; x++, tp += 2) //另一半环
    				answer += a[tp] * a[tp + 2];
    			answer += a[p] * a[p + 1] + a[p + ring - 1] * a[p + ring - 2]; //最后处理两个半环链接的问题
    		}
    		printf("%lld
    ", answer);
    		record[ring] = answer; //记录
    	}
    	return 0;
    }
    
  • 相关阅读:
    flask 跨域问题
    pip 命令参数说明
    关于ASP.NET动态加载控件的几点实用总结
    记录代码运行耗时的写法
    DevExpress AspxGridView数据绑定
    发现一个Membership的bug
    asp.net页面中文件下载的2种方式
    【部分转】innerText 跟 innerHTML区别
    gridview 的添加删除等技巧 全部按名称取值
    关于Linq to DataTable not in的写法
  • 原文地址:https://www.cnblogs.com/macesuted/p/solution-P6187.html
Copyright © 2011-2022 走看看