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

A - 今年暑假不AC

#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#include<stdio.h>
#define MAXN 3000
using namespace std;
struct node
{
     int start,end;
}record[MAXN];
//结束时间早的优先
bool cmp(const node& a,const node& b){ return a.end<b.end; }
int main()
{
   int n;
   while(1)
   {
       cin>>n;
       if(n==0)break;
       for(int i=0;i<n;++i)
            cin>>record[i].start>>record[i].end;
       sort(record,record+n,cmp);
       int count=0;
       int lastend=-1;
       for(int i=0;i<n;++i)
       {
           if(record[i].start>=lastend)
           {
               count++;
               lastend = record[i].end;
           }
       }
       cout<<count<<endl;
   }
    return 0;
}

B - 迷瘴

我可烦死这道题了,精度哪里老是死,气死了

#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#include<stdio.h>
#define MAXN 105
using namespace std;
int record[MAXN];
int n,V,W;
struct node
{
    float e;//分子
    int  v;//分母
}med;
int main()
{
   int C;cin>>C;
   while(C--)
   {
       cin>>n>>V>>W;
       for(int ii=0;ii<n;++ii)
            cin>>record[ii];
       sort(record,record+n);
       int i;med.e=0,med.v=0;

       for(i=0;i<n;++i)
       {
           if((float)(med.e*med.v+record[i]*1.0/100*V)*1.0/(med.v+V)>W*1.0/100)
           {
                printf("%d %.2lf\n",med.v,med.e);
                break;
           }
           else
           {
               med.e =(float)(med.v*med.e+record[i]*1.0/100*V)*1.0/(med.v+V);;//分子
               med.v +=V;
           }
       }
       if(i==n)
            printf("%d %.2lf\n",med.v,med.e);
   }
    return 0;
}

Entropy POJ - 1521 

#include<iostream>
#include<algorithm>
#include<queue>
#include<stdio.h>
#define ll long long
using namespace std;

int main()
{
    string s;
    // 优先队列,最小的在最前面,优先队列默认是从大到小排序
    while(getline(cin,s)&&s!="END")
    {
        int t=1;
        sort(s.begin(),s.end());
        priority_queue<int,vector<int>,greater<int> >Q;
        for(int i=1;i<s.length();++i)
        {
            if(s[i]!=s[i-1])
            {
                Q.push(t);
                t = 1;
                //统计每一个字符出现的频次,加入优先队列
            }
            else t++;
        }
        Q.push(t);//最后一个没得比较,直接加入队列
        int  ans=0;
        while(Q.size()>1)
        {
            int a = Q.top();Q.pop();
            int b= Q.top();Q.pop();
            //cout<<a<<","<<b<<","<<ans<<endl;
            ans += a+b;
            Q.push(a+b);
        }

        if(!ans)
            ans=s.length();
        while(!Q.empty()) Q.pop();

        int ascii=s.length()*8;
        printf("%d %d %.1f\n",ascii,ans,(ascii*1.0)/(ans*1.0));
    }

    return 0;
}

 

Strange fuction HDU - 2899 

#include<iostream>
#include<algorithm>
#include<queue>
#include<stdio.h>
#include<math.h>
#define ll long long
using namespace std;
const double eps=1e-8;
double y;
double func(double x)
{
    return 6*pow(x,7.0)+8*pow(x,6.0)+7*pow(x,3.0)+5*pow(x,2.0)-y*x;
}
double solve()
{
    double T = 100;
    double delta = 0.98;
    double x=50.0;
    double now=func(x);
    double ans=now;
    while(T>eps)
    {
        int f[2]={1,-1};
        double newx = x+f[rand()%2]*T;
        if(newx>=0&&newx<=100)
        {
            double next = func(newx);
            ans = min(ans,next);
            if(now - next>eps) {
                x = newx;
                now = next;
            }

        }
        T *=delta;
   
    return ans;
}
int main()
{
    int cas;
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%lf",&y);
        printf("%.4f\n",solve());
    }
    return 0;
}

 

Doing Homework again HDU - 1789 

  • 第一种排序按截止日期从小到大排序,以保证可以完成最多的作业,截止日期相同的按照惩罚从大到小排序,以保证惩罚最小
  • 第二种排序利用优先队列,按照惩罚从小到大排序,将第一个排序法中取出的作业放到这个优先队列中。
  • 发生超时,从优先队列中取出第一个数用它的惩罚与当前的比较,如果队列中的惩罚比他小,则把这个数加入队列,原来的作业放弃,否则这个作业就放弃
#include<iostream>
#include<algorithm>
#include<queue>
#include<stdio.h>
#include<math.h>
#define ll long long
using namespace std;
const int M=1004;

struct node
{
    int deadline;
    int reduced_score;
}course[M];
int N;
bool cmp(node &a,node &b)
{
    if(a.deadline==b.deadline)
        return a.reduced_score>b.reduced_score;
    else
        return a.deadline<b.deadline;
}
struct cmp2
{
    bool operator()(node a,node b)
    {
        return a.reduced_score>b.reduced_score;
    }
};
int solve()
{
    sort(course,course+N,cmp);
    int red_sum=0;
    int TAG=1;

    priority_queue<node,vector<node>,cmp2> q;
    for(int i=0;i<N;++i)
    {
       if(course[i].deadline<TAG)
       {
           if(q.top().reduced_score<course[i].reduced_score)
           {
               red_sum+=q.top().reduced_score;
               q.pop();
               q.push(course[i]);
           }
           else
            red_sum+=course[i].reduced_score;
       }
       else
       {
           q.push(course[i]);
           TAG++;
       }
    }
    return red_sum;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);

        for(int i=0;i<N;++i)
        {
            scanf("%d",&course[i].deadline);
        }
        for(int i=0;i<N;++i)
        {
            scanf("%d",&course[i].reduced_score);
        }
        printf("%d\n",solve());
    }
    return 0;
}

 

饭卡 HDU - 2546 

01背包,从小到大排序,用前n-1个填m-5的背包

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAX 1007
using namespace std;
int price[MAX],dp[MAX],m,n;
int main()
{
    while(~scanf("%d",&n)&&n!=0)
    {
        for(int i=0;i<n;++i)
        {
            cin>>price[i];
        }
        cin>>m;
        if(m<5)
        {
            cout<<m<<endl;
        }
        else
        {
            sort(price,price+n);
            memset(dp,0,sizeof(dp));
            for(int i=0;i<n-1;++i)
            {
                for(int j=m-5;j>=price[i];--j)
                {
                    dp[j]=max(dp[j],dp[j-price[i]]+price[i]);
                }
            }
            cout<<m-dp[m-5]-price[n-1]<<endl;
        }
    }
    return 0;
}

coins HDU - 3348

这里一开始就给出了有序的从小到大的数值。先算如何让硬币最少的问题,如何让硬币最多可以转化为计算sum(所有的硬币总价钱)-p(商品的价钱)时,硬币如何最少。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAX 1000007
using namespace std;
int a[5],p,T;
int b[5]={1,5,10,50,100};
bool cmp(int &a,int &b)
{
    return a>b;
}
int Count(int p)
{
    int t=0,min_t=0;
    for(int i=4;i>=0;--i)
    {
        min_t=min(p/b[i],a[i]);
        p -=b[i]*min_t;
        t+=min_t;
        if(p==0) break;
    }
    if(p==0)
        return t;
    else
        return -1;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        cin>>p;
        int sum=0,coin=0;
        for(int i=0;i<5;++i)
        {
            cin>>a[i];
            sum+=a[i]*b[i];
            coin+=a[i];
        }
        int res=Count(p);
        if(res==-1)
            cout<<"-1 -1"<<endl;
        else
            cout<<res<<" "<<coin-Count(sum-p)<<endl;
    }
    return 0;
}

#handwriting

  • 任一面值的硬币,大于比他小的所有硬币的面值之和。可以用贪心法,例如以2的倍数递增的1、2、4、8等,这样的面值就符合条件
posted @ 2020-03-09 20:36  东坡肉肉君  阅读(167)  评论(0编辑  收藏  举报