湖中大2019寒假训练day5 贪心专题题解

第一题理解起来应该不难,就是个累加过程。每次要从小的开始累加,才能保证累加和最小。

所以我们第一步把输入的数组排好序,按次序累加即可

#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#define  LL long long
#define  ULL unsigned long long
#define mod 1000000007
#define INF 0x7ffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define MODD(a,b) (((a%b)+b)%b)
using namespace std;
int a[10005];
int main()
{
  int n;
  scanf("%d",&n);
  while(n--){
    int m;
    scanf("%d",&m);
    for(int i=0;i<m;i++) scanf("%d",&a[i]);
    sort(a,a+m);
    int m1=m-1,flag=0,j=0,sum=0;
    while(m1--){
        sum = a[j]+a[j+1];
        a[j+1] =sum;
        flag+=sum;
        j++;

    }
    printf("%d\n",flag);
  }



  return 0;
}








经典的区间dp,详情可以见紫书p232

#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#define  LL long long
#define  ULL unsigned long long
#define mod 1000000007
#define INF 0x7ffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define MODD(a,b) (((a%b)+b)%b)
using namespace std;
struct node
{
    int start,endding;
}stu[105];
bool cmp(node a,node b){
    if(a.endding!=b.endding)
   return b.endding>a.endding;
   else{

   }
}
int main()
{
    int n,cot = 1;;
    while(~scanf("%d",&n)){
        if(n==0) return 0;
        for(int i=0;i<n;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            stu[i].start=a;
            stu[i].endding=b;

        }
        sort(stu,stu+n,cmp);
        cot = 1;
        node p=stu[0];
        for(int i=0;i<n-1;i++){

            if(p.endding<=stu[i+1].start) cot++,p=stu[i+1];
            //printf("%d--%d\n",stu[i].start,stu[i].endding);
        }
        printf("%d\n",cot);
    }



  return 0;
}








C:

贪心策略可以很简单的看出来,就是样例的 Javabeen/catfood 最大的先选,此时才是换取Javabeen最大的数量

#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
struct node
{
    int fa;
    int j;
    double cot;
}rom[1005];
bool cmp(node a,node b)
{
    return a.cot>b.cot;
}
int main()
{
    int n;
    double sumfa;
    while(~scanf("%lf%d",&sumfa,&n))
    {
        if(sumfa==n&&n==-1) return 0;
        int i;
        for(i=0;i<n;i++){
            scanf("%d%d",&rom[i].j,&rom[i].fa);
            rom[i].cot=(rom[i].j*1.0/rom[i].fa);
        }
        sort(rom,rom+n,cmp);
        
        double sum=0;
        for(i=0;i<n;i++){
            if(sumfa>=rom[i].fa){
                sumfa-=rom[i].fa;
                sum+=rom[i].j;


            }
            else{
                if(sumfa>=0)
                sum+=rom[i].j*1.0*sumfa/rom[i].fa;
                break;
            }
          
        }
        printf("%.3lf\n",sum);

    }
    return 0;
}

D:

这一题的策略需要细想,题目要求是要扣分越少越好,并不是做完的作业越多越好。所以我们贪心的策略的就是把分值高的排在前面先完成,分值相同的,截止日期小的排前面。

这样一来就会有一个问题,我们假如说有 1---1和2---7 这两门课 我们排好序后的顺序为 2---7&1---1,我们先完成的第二天完成的作业,到第二天就不能完成第一天的作业了。所以我们从后往前来推时间,这样可以避免这种问题。

还有一点就是要标记当天,不标记的话可能导致这一天完成多次作业。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
struct node
{
    int day;
    int score;
}a[10005];
int vis[10005];
int cmp(node a,node b)
{
    if(a.score!=b.score)
        return a.score>b.score;
    else return a.day<b.day;
}

int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        int m;
        scanf("%d",&m);
        memset(vis,0,sizeof(vis));
        int i,j;
        for(i=0;i<m;i++) scanf("%d",&a[i].day);
        for(i=0;i<m;i++) scanf("%d",&a[i].score);
        sort(a,a+m,cmp);
        int sum=0;
        for(i=0;i<m;++i)//这两层for循环是关键
        {
            j=a[i].day;
            for(;j>=1;--j)//标记哪天已经完成了作业
            {
                if(!vis[j])//没有作业的时候就标记,有作业就往前推 --j
                {
                    vis[j]=1;
                    break;
                }

            }
            if(j==0)
                sum+=a[i].score;
        }
        printf("%d\n",sum);

    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40620465/article/details/86595460
今日推荐