贪心+huffman编码+模拟退火+分治(一)

(一)贪心

1.A - 今年暑假不AC

“今年暑假不AC?” 
“是的。” 
“那你干什么呢?” 
“看世界杯呀,笨蛋!” 
“@#$%^&*%...”

确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。 
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)

Input输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。 
Output对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。Sample Input

12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0

Sample Output

5解题思路:贪心思路:将每个数据用pair储存起来,根据结束时间进行从小到大排序,在循环模拟时,若果下一个的起始时间<上一个的结束时间,则可以++,并将该结束时间作为下回判断的结束时间;否则循环下一个。代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define x first
#define y second
using namespace std;
const int N=110;
typedef  pair<int,int> PII;
int t;
PII f[N];
int main()
{
    int s,e,i,j,n;
    while(scanf("%d",&n)&&n)
    {
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&s,&e);
            f[i].x=e,f[i].y=s;
        }
        sort(f,f+n);
        int ans=1;
        int tem=f[0].x;
        for(i=1;i<n;i++)
        {
            if(f[i].y>=tem)
            {
                ans++;
                tem=f[i].x;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

2.B - 迷瘴

通过悬崖的yifenfei,又面临着幽谷的考验—— 
幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死。 
幸好yifenfei早有防备,提前备好了解药材料(各种浓度的万能药水)。现在只需按照配置成不同比例的浓度。 
现已知yifenfei随身携带有n种浓度的万能药水,体积V都相同,浓度则分别为Pi%。并且知道,针对当时幽谷的瘴气情况,只需选择部分或者全部的万能药水,然后配置出浓度不大于 W%的药水即可解毒。 
现在的问题是:如何配置此药,能得到最大体积的当前可用的解药呢? 
特别说明:由于幽谷内设备的限制,只允许把一种已有的药全部混入另一种之中(即:不能出现对一种药只取它的一部分这样的操作)。 

Input输入数据的第一行是一个整数C,表示测试数据的组数; 
每组测试数据包含2行,首先一行给出三个正整数n,V,W(1<=n,V,W<=100); 
接着一行是n个整数,表示n种药水的浓度Pi%(1<=Pi<=100)。 
Output对于每组测试数据,请输出一个整数和一个浮点数; 
其中整数表示解药的最大体积,浮点数表示解药的浓度(四舍五入保留2位小数); 
如果不能配出满足要求的的解药,则请输出0 0.00。 
Sample Input

3
1 100 10
100
2 100 24
20 30
3 100 24
20 20 30

Sample Output

0 0.00
100 0.20
300 0.23
解题思路:贪心思路就是优先选择浓度低的,对所有解药进行sort排序,再结合前缀和,从后往前进行遍历,找到第一个浓度小于等于目标浓度的体积时结束,输出;特别注意:double x=((s[i]*1.0/100)*v)/((i+1)*v);代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
int c,n,v;
int f[110],s[110];
int w;
int main()
{
    int i,j;
    cin>>c;
    while(c--)
    {
        cin>>n>>v>>w;
        for(i=0;i<n;i++)
            cin>>f[i];
        double dow=w/100.00;
        sort(f,f+n);
        s[0]=f[0];
        for(i=1;i<n;i++)
        {
            s[i]=s[i-1]+f[i];
        }
        bool flag=false;
        for(i=n-1;i>=0;i--)
        {
            double x=((s[i]*1.0/100)*v)/((i+1)*v);
            if(x<dow||fabs(x-dow)<1e-8)
            {
                flag=true;
                cout<<(i+1)*v<<" ";
                printf("%.2f\n",x);
                break;
            }
        }
        if(flag==false)
            cout<<"0 0.00"<<endl;
    }
    return 0;
}

(二)模拟退火

1.Strange fuction

Now, here is a fuction: 
  F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100) 
Can you find the minimum value when x is between 0 and 100.

Input

The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has only one real numbers Y.(0 < Y <1e10)

Output

Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100.Sample Input

2
100
200

Sample Output

-74.4291
-178.8534
解题思路:该题可用二分的思想来解决。代码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
double find(double x,double y)
{
    return 6*pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*pow(x,2)-y*x;
}

double check(double y)
{
    double l=0,r=100;
    while(r-l>1e-8)
    {
        double mid=(l+r)/2;
        double rmid=(mid+r)/2;
        if(find(mid,y)<find(rmid,y))
            r=rmid;
        else
            l=mid;
    }
    return l;
}

int main()
{
    int t,i;
    double y;
    cin>>t;
    while(t--)
    {
        cin>>y;
        double key=check(y);
        printf("%.4f\n",find(key,y));
    }
    return 0;
}



原文地址:https://www.cnblogs.com/xiaofengzai/p/12255249.html

时间: 2024-10-14 00:48:11

贪心+huffman编码+模拟退火+分治(一)的相关文章

Huffman编码学习笔记

主要是在学算导,觉得算导译到中国真是中国人民的福音. 一.编码 编码就是选择有意义的01串,令其首尾相接组成文本.我们并非可以随便挑选01串,原因在于它们是首尾相接的,这为我们识别造成了一些困难.比如说我们不能在文本000000中分清字符00与000. 一般我们使用的方式是定长字符:但更好的方式是前缀码,算导中写道"虽然我们这里不会证明,但与任何字符编码相比,前缀码确实可以保证达到最优数据压缩率.",这显然是一个flag,将来一定会有比前缀码更好的编码方式的. 二.Huffman编码便

基于Huffman编码的压缩软件的Python实现

哈夫曼编码是利用贪心算法进行文本压缩的算法,其算法思想是首先统计文件中各字符出现的次数,保存到数组中,然后将各字符按照次数升序排序,挑选次数最小的两个元素进行连结形成子树,子树的次数等于两节点的次数之和,接着把两个元素从数组删除,将子树放入数组,重新排序,重复以上步骤.为了解压,在压缩时首先往文件中填入huffman编码的映射表的长度,该表的序列化字符串,编码字符串分组后最后一组的长度(编码后字符串长度模上分组长度),最后再填充编码后的字符串.本算法中以一个字节,8位作为分组长度,将编码后二进制

UVa10954 Add All (Huffman编码,优先队列)

链接:http://vjudge.net/problem/UVA-10954 分析:Huffman编码建立过程,每次贪心选取两个当前最小数,从集合中删去,然后把它们的和放回集合,用优先队列去模拟集合而且可以优化取最小数过程. 1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 6 const int maxm = 500 + 5; 7 8 int

Jcompress: 一款基于huffman编码和最小堆的压缩、解压缩小程序

前言 最近基于huffman编码和最小堆排序算法实现了一个压缩.解压缩的小程序.其源代码已经上传到github上面: Jcompress下载地址 .在本人的github上面有一个叫Utility的repository,该分类下面有一个名为Jcompress的目录便是本文所述的压缩.解压缩小程序的源代码.后续会在Utility下面增加其他一些实用的小程序,比如基于socket的文件断点下载小程序等等.如果你读了此文觉得还不错,不防给笔者的github点个star, 哈哈.在正式介绍Jcompres

基于二叉树和数组实现限制长度的最优Huffman编码

具体介绍详见上篇博客:基于二叉树和双向链表实现限制长度的最优Huffman编码 基于数组和基于链表的实现方式在效率上有明显区别: 编码256个符号,符号权重为1...256,限制长度为16,循环编码1w次,Release模式下.基于链表的耗时为8972ms,基于数组的耗时为1793ms,速度是链表实现方式的5倍. 详细代码例如以下: //Reference:A fast algorithm for optimal length-limited Huffman codes.pdf,http://p

Huffman 编码压缩算法

前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法.相信大家应该听说过 David Huffman 和他的压缩算法—— Huffman Code,一种通过字符出现频率,Priority Queue,和二叉树来进行的一种压缩算法,这种二叉树又叫Huffman二叉树 —— 一种带权重的树.从学校毕业很长时间的我忘了这个算法,但是网上查了一下,中文社区内好像没有把这个算法说得很清楚的文章,尤其是树的构造,而正好看到一篇国外的文章<A Simple Examp

为什么Huffman编码不会发生冲突

关于Huffman编码,这里有一篇漂亮的介绍 http://coolshell.cn/articles/7459.html 似乎介绍Huffman编码的都会有一句“Huffman编码不会发生冲突,即不存在某个编码是另一个编码的前缀”.但是也似乎都没有解释为什么. 细细想明白了之后,觉得似乎又没什么深奥的原理.废话少说,上图. 以上面的图为例子,我们假设这是一个生成Huffman编码的二叉树. 1)所谓的Huffman编码其实就是各个叶节点的路径编码.比如节点H就是010(用左0,右1的规则) 2

Huffman编码

Huffman编码用来解决最小二叉树问题... 用堆来维护,所用用优先队列(稍微修改一下放入方式)每次将两个权值最小的取出来,然后把他们的和再放进去,重复这个操作就可以解决了 1 #include<iostream> 2 #include<queue> 3 using namespace std; 4 typedef long long ll; 5 6 int main(){ 7 priority_queue<int>que; 8 int n, x; 9 cin>

Huffman编码之文件的解/压缩

问题描述:           生活中文件压缩技术可谓随处可见,在数据的密集型传输中文件压缩是一项重要的实用性技术.例如:较大文件的下载,传输等.常见的文件压缩工具有winRAR,2345好压,快压(KuaiZip)等,这些工具已经开发的相当牛逼,但是作为入门级的程序员来说,不能只停留在观摩的立场上,扮演使用者的角色.有必要深入了解其底层的基础实现方式,掌握基础的文件压缩原理,所以在此将其视为一个小型项目列出,以供大家交流探讨,相互学习.... ★在此之前,先来说说什么是文件压缩,用以抛出一个基