NYOJ 贪心算法题目汇总(一)

喷水装置(一)

时间限制:
3000 ms  |  内存限制:
65535 KB 难度:
3

描述
现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1<i<600)个,并且一定能把草坪全部湿润,你要做的是:选择尽量少的喷水装置,把整个草坪的全部湿润。

输入
第一行m表示有m组测试数据

每一组测试数据的第一行有一个整数数n,n表示共有n个喷水装置,随后的一行,有n个实数ri,ri表示该喷水装置能覆盖的圆的半径。

输出
输出所用装置的个数
样例输入
2
5
2 3.2 4 4.5 6 
10
1 2 3 1 2 1.2 3 1.1 1 2
样例输出
2
5
来源
[苗栋栋]原创
上传者

苗栋栋

 
#include<iostream>
#include<vector>
#include<functional>
#include<algorithm>
#include<cmath>
using namespace std;
double Length(double R,double b)
{
	return 2*sqrt(R*R-b*b/4);
}
int main()
{
	const double l=20,w=2;
	int n;
	cin>>n;
	while(n--)
	{
		int m;
		cin>>m;
		double R;
		vector<double> Rs;
		while(m--)
		{
			cin>>R;
			Rs.push_back(R);
		}
		sort(Rs.begin(),Rs.end(),greater<double>());
		double sum=0;
		int i;
		for(i=0;i!=Rs.size();i++)
		{
			if (sum>l) break;
			sum+=Length(Rs[i],w);
		}
		cout<<i<<endl;
	}
}        

喷水装置(二)

时间限制:
3000 ms  |  内存限制:
65535 KB 难度:
4

描述
有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。

输入
第一行输入一个正整数N表示共有n次测试数据。

每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。

随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。

输出
每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。

如果不存在一种能够把整个草坪湿润的方案,请输出0。

样例输入
2
2 8 6
1 1
4 5
2 10 6
4 5
6 5
样例输出
1
2
来源
《算法艺术与信息学竞赛》
上传者
张云聪
#include <stdio.h>    
#include <math.h>    
#include <algorithm>    
using std::sort;    
struct node{    
    double left, right;    
}s[1005];    
int cmp(node a, node b)    
{    
    return a.left < b.left;    
}    
int main()    
{    
    int n, t;    
    double w, h;    
    scanf("%d", &t);    
    while(t --){    
        scanf("%d%lf%lf", &n, &w, &h);    
        h /= 2;  //要除去2    
        int i, j;    
        double temp, r;    
        for(i = 0, j = 0; i < n; i ++){    
            scanf("%lf%lf", &temp, &r);    
            if(r <= h) continue;//如果不能,喷洒到俩边或刚好喷洒到两边    
            else{    
                double temp1 = sqrt(r*r-h*h);//求最长能够形成矩形的宽度    
                s[j].left = temp -temp1;//左边界    
                s[j++].right = temp+temp1;//右边界    
            }    
        }    
        sort(s, s+j, cmp);//排序    
     
        if(s[0].left > 0) {printf("0\n"); continue;} //如果第一个要大于0, 就是0到不了,直接输出0    
        double end = 0;    
        i = 0;    
        int cou = 0;    
        while(end <= w&&i < j&&cou <= n){//区间覆盖核心代码这里的    
            temp = end;       //temp = end =0;
            while(s[i].left <= end&&i <j ){    
                if(s[i].right > temp) temp = s[i].right;    
                i++;    
            }    
            end = temp;
            ++cou;    
        }    
        if(end < w){    
            printf("0\n");    
        }    
        else{     
            printf("%d\n", cou);    
        }    
    }    
    return 0;    
}    

会场安排问题

时间限制:
3000 ms  |  内存限制:
65535 KB 难度:
4

描述
学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动。现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。

输入
第一行是一个整型数m(m<100)表示共有m组测试数据。

每组测试数据的第一行是一个整数n(1<n<10000)表示该测试数据共有n个活动。

随后的n行,每行有两个正整数Bi,Ei(0<=Bi,Ei<10000),分别表示第i个活动的起始与结束时间(Bi<=Ei)

输出
对于每一组输入,输出最多能够安排的活动数量。

每组的输出占一行

样例输入
2
2
1 10
10 11
3
1 10
10 11
11 20
样例输出
1
2
提示
注意:如果上一个活动在t时间结束,下一个活动最早应该在t+1时间开始
来源
经典题目
上传者
张云聪
//对结束时间排序,尽量选择结束时间早的。局部最优——整体最优 
#include<stdio.h>
#include <vector>
#include<algorithm>
#include<math.h>
using namespace std;

struct activ 
{
	int begin;
	int end;
};
bool cmp( activ a,activ b)
{
	return a.end<b.end;
}
int main()
{
	int n;
	scanf("%d",&n);
	while (n--)
	{
		int m;
		scanf("%d",&m);
		vector<activ> vec;
		for(int i=0;i<m;i++)
		{
			activ a;
			scanf("%d%d",&a.begin,&a.end);
			vec.push_back(a);
		}
		
		sort(vec.begin(),vec.end(),cmp);	
		int count=vec.size();
		int k=0;
		for (int i=1;i<vec.size();i++)
		{
			if(vec[i].begin <= vec[k].end) 
				count--;
			else k=i;
		}
		printf("%d\n",count);
	}
	
	return 0;
}        

Gone Fishing

时间限制:
3000 ms  |  内存限制:
65535 KB 难度:
5

描述
John is going on a fishing trip. He has h hours available (1 <= h <= 16), and there are n lakes in the area (2 <= n <= 25) all reachable along a single, one-way road. John starts at lake 1, but he can finish at any lake he wants. He can only travel from one lake to the next one, but he does not have to stop at any lake unless he wishes to. For each i = 1,…,n – 1, the number of 5-minute intervals it takes to travel from lake i to lake i + 1 is denoted ti (0 < ti <=192). For example, t3 = 4 means that it takes 20 minutes to travel from lake 3 to lake 4. To help plan his fishing trip, John has gathered some information about the lakes. For each lake i, the number of fish expected to be caught in the initial 5 minutes, denoted fi( fi >= 0 ), is known. Each 5 minutes of fishing decreases the number of fish expected to be caught in the next 5-minute interval by a constant rate of di (di >= 0). If the number of fish expected to be caught in an interval is less than or equal to di , there will be no more fish left in the lake in the next interval. To simplify the planning, John assumes that no one else will be fishing at the lakes to affect the number of fish he expects to catch. 

Write a program to help John plan his fishing trip to maximize the number of fish expected to be caught. The number of minutes spent at each lake must be a multiple of 5. 

输入
You will be given a number of cases in the input. Each case starts with a line containing n. This is followed by a line containing h. Next, there is a line of n integers specifying fi (1 <= i <=n), then a line of n integers di (1 <=i <=n), and finally, a line of n – 1 integers ti (1 <=i <=n – 1). Input is terminated by a case in which n = 0. 

输出
For each test case, print the number of minutes spent at each lake, separated by commas, for the plan achieving the maximum number of fish expected to be caught (you should print the entire plan on one line even if it exceeds 80 characters). This is followed by a line containing the number of fish expected. 

If multiple plans exist, choose the one that spends as long as possible at lake 1, even if no fish are expected to be caught in some intervals. If there is still a tie, choose the one that spends as long as possible at lake 2, and so on. Insert a blank line between cases. 

样例输入
2 
1 
10 1 
2 5 
2 
4 
4 
10 15 20 17 
0 3 4 3 
1 2 3 
4 
4 
10 15 50 30 
0 3 4 3 
1 2 3 
0 
样例输出
45, 5 
Number of fish expected: 31 

240, 0, 0, 0 
Number of fish expected: 480 

115, 10, 50, 35 
Number of fish expected: 724 

来源
East Central North A
上传者
张云聪

这个还没看懂…….

 
#include<iostream>
#include<algorithm>
#include<numeric>
#include<iterator>
#include<string>
#include<string.h>
using namespace std;

const int MAX=30;
int fi[MAX],di[MAX],ti[MAX];
int bestresult[MAX]={0},bestfishnum=-1;
int fishing(int end,int fi[],int di[],int ti[],int h)
{
	int tmpfi[MAX],cost=accumulate(ti+1,ti+end,0),result[MAX]={0},fishnum=0;
	memcpy(tmpfi,fi,sizeof(tmpfi));
	while(cost+5<=h*60)
	{
		int max_pos=max_element(tmpfi+1,tmpfi+end+1)-tmpfi;
		//if (tmpfi[max_pos]==0) break;
		result[max_pos]++;
		fishnum+=tmpfi[max_pos];
		tmpfi[max_pos]-=di[max_pos];
		if (tmpfi[max_pos]<0) tmpfi[max_pos]=0;
		cost+=5;
	}
	if (fishnum>bestfishnum) 
	{
		bestfishnum=fishnum;
		memcpy(bestresult,result,sizeof(result));
	}
	return fishnum;
}
void print(int result[],int n,int fishnum)
{
	string s;
	for(int i=1;i<=n;i++)
	{
		cout<<s<<result[i]*5;
		s=", ";
	}
	cout<<endl<<"Number of fish expected: "<<fishnum<<endl<<endl;
}
void init()
{
	memset(bestresult,0,sizeof(bestresult));
	bestfishnum=-1;
}
int main()
{
		int n,h;
	int m;
	while(cin>>n>>h)
	{
		if (n==0) exit(0);
		for(int i=1;i<=n;++i)
		{
			cin>>fi[i];
		}
		for(int i=1;i<=n;++i)
		{
			cin>>di[i];
		}
		for(int i=1;i<n;++i)
		{
			cin>>m;
			ti[i]=5*m;
		}
		for(int i=1;i<=n;++i)
		{
			fishing(i,fi,di,ti,h);
		}
		print(bestresult,n,bestfishnum);
		init();
		

	}
}
        

过河问题

时间限制:
1000 ms  |  内存限制:
65535 KB 难度:
5

描述

在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。 

输入
第一行是一个整数T(1<=T<=20)表示测试数据的组数

每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河

每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0<Si<=100)

输出
输出所有人都过河需要用的最少时间
样例输入
1
4
1 2 5 10
样例输出
17
来源
POJ
上传者
张云聪
/*
分析:
如果n==1或者n==2,所有人直接过河即可;
如果n==3,用时最短的和用时最长的一起过去,然后用时最短的回来,再和剩下的一个人过去 ;
如果n>=4,设a[0]表示用时最短的人所用的时间,a[1]为用时第二短的人所用的时间,a[n-1]表示用时最长的人所用的时间,a[n-2]表示用时第二长的人所用的时间。那么:
当2a[1] + a[0] + a[n-1] > 2a[0] + a[n-1] + a[n-2]时,就先让用时最短的人和用时最长的人一起过去,然后用时最短的回来,接着让用时最短的和用时第二长的一起过去,再让用时最短的回来。
否则,就先让用时最短的和用时第二短的一起过去,然后用时最短的回来,接着让用时最长和用时第二长的一起过去,再让用时第二短的回来。这样就相当于剩下了n-2个人。
对这n-2个人执行相同的操作,直到剩下不足4个人即可。
*/
#include<stdio.h>  
#include<algorithm>  
using namespace std;  
int a[1010];  
int main()  
{  
    int T;  
    scanf("%d",&T);  
    while(T--)  
    {  
        int N,i,sum=0;  
        scanf("%d",&N);  
        for(i=0;i<N;i++)  
        scanf("%d",&a[i]);  
        sort(a,a+N); 
		//方案一: 
        while(N>3){//以四个人为一个单位选出局部最优解,局部的最优得出全局的最优   
            if((a[1]+a[0]+a[N-1]+a[1]+a[1])<(a[1]+a[0]+a[N-1]+a[0]+a[N-2]))  
            sum+=a[1]+a[0]+a[N-1]+a[1];  
            else sum+=a[N-1]+a[0]+a[N-2]+a[0];  
            N=N-2;  
        }  
        if(N==1)  
        sum+=a[0];  
        else if(N==2)  
        sum+=a[1];  
        else if(N==3)  
        sum+=a[1]+a[0]+a[2];  
        printf("%d\n",sum);  
    }  
    return 0;  
} 



while(n >= 4)  
{  
    if((a[1] * 2 + a[n-1] + a[0]) > (2 * a[0] + a[n-1] + a[n-2]))  
    {  //求出最长的两个人过桥所用的最短时间  
        sum += a[n-1]; //用时最短的和用时最长的一起过去  
        sum += a[0]; //用时最短的回来  
        sum += a[n-2]; //用时最短的和用时第二长的一起过去  
        sum += a[0]; //用时最短的回来  
    }  
    else  
    {  
        sum += a[1]; //最短的和第二短的一起过去  
        sum += a[0]; //最短的回来  
        sum += a[n-1]; //最长的和第二长的一起过去  
        sum += a[1]; //第二短的回来  
    }  
    n -= 2;  
}  

独木舟上的旅行

时间限制:
3000 ms  |  内存限制:
65535 KB 难度:
2

描述

进行一次独木舟的旅行活动,独木舟可以在港口租到,并且之间没有区别。一条独木舟最多只能乘坐两个人,且乘客的总重量不能超过独木舟的最大承载量。我们要尽量减少这次活动中的花销,所以要找出可以安置所有旅客的最少的独木舟条数。现在请写一个程序,读入独木舟的最大承载量、旅客数目和每位旅客的重量。根据给出的规则,计算要安置所有旅客必须的最少的独木舟条数,并输出结果。

输入
第一行输入s,表示测试数据的组数;

每组数据的第一行包括两个整数w,n,80<=w<=200,1<=n<=300,w为一条独木舟的最大承载量,n为人数;

接下来的一组数据为每个人的重量(不能大于船的承载量);

输出
每组人数所需要的最少独木舟的条数。
样例输入
385 65 84 85 80 84 8390 390 45 60100 550 50 90 40 60
样例输出
533
上传者
李剑锋

/*   
   *先把各个人的体重排序,然后计算最重的人和最轻的 
   *人能否同乘一条舟,如果不能,则最重的人就要单独 
   *乘坐一条舟,再求最轻的和第二重的人的和,依次比较。 
*/  
#include<stdio.h>  
int main(){  
    int n,w,m,i,a[300],t;  //w为最大承载量,m为人数   
                           //n为测试组数,a[300]为存放人数体重   
    scanf("%d",&n);  
    //n组测试数据   
    while(n--){  
        scanf("%d%d",&w,&m);  
        int  k=0,j=0;  
        //输入人数体重   
        for(i=0;i<m;i++){  
            scanf("%d",&a[i]);  
        }  
        //对体重进行排序   
        for(i=0;i<m;i++){  
            for(j=i+1;j<m;j++){  
                if(a[i]>a[j]){  
                    t = a[i];  
                    a[i] = a[j];  
                    a[j] = t;  
                }  
            }  
        }  
          
        for(i=0,j=m-1;i<=j;){  
            if(a[i]+a[j]<=w){  
                i++;  
                j--;  
                k++;  
            }else if(i==j){  
                k++;  
            }else{  
                j--;  
                k++;  
            }  
        }  
        printf("%d\n",k);  
    }  
    return 0;  
}

阶乘之和

时间限制:
3000 ms  |  内存限制:
65535 KB 难度:
3

描述

给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3!,如果是,则输出Yes,否则输出No;

输入
第一行有一个整数0<m<100,表示有m组测试数据;

每组测试数据有一个正整数n<1000000;

输出
如果符合条件,输出Yes,否则输出No;
样例输入
2910
样例输出
YesNo
上传者
李剑锋
//局部最优,每次选择最大的 
#include<cstdio>    
int a[10]={1,2,6,24,120,720,5040,40320,362880};    
int main()    
{    
    int m,i,n;    
    scanf("%d",&m);    
    while(m--)    
    {    
        scanf("%d",&n);    
        for(i=8; i>=0; i--)    
            if(n>=a[i])    
                n-=a[i];    
        if(n==0)    
            printf("Yes\n");    
        else    
            printf("No\n");     
    }    
} 

背包问题

时间限制:
3000 ms  |  内存限制:
65535 KB 难度:
3

描述
现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w<=10);如果给你一个背包它能容纳的重量为m(10<=m<=20),你所要做的就是把物品装到背包里,使背包里的物品的价值总和最大。

输入
第一行输入一个正整数n(1<=n<=5),表示有n组测试数据;

随后有n测试数据,每组测试数据的第一行有两个正整数s,m(1<=s<=10);s表示有s个物品。接下来的s行每行有两个正整数v,w。

输出
输出每组测试数据中背包内的物品的价值和,每次输出占一行。
样例输入
1
3 15
5 10
2 8
3 9
样例输出
65
来源
[苗栋栋]原创
上传者
苗栋栋

/* 
  思路:使用贪心算法。为了使背包里的物品总价值最大,先装单位价值最大的,依次类推, 
        整放物品,不能整放分割放   
 
  1.定义一个结构体,变量名bao[10],里面定义 单位价值和每个物品重量  
  2.对物品的单位 价值从大到小排序。  
  3.输入信息,并计算出每一个物品的总价值。  
  4.整放物品,计算出满足条件的物品的总价值,总质量。  
  5.分割,背包所容纳的最大质量减去目前的质量乘以分割物品的价值,计算总价值。跳出循环  
*/  
   
//注意:不要忘记每次循环都要初始化数组   
#include<stdio.h>  
#include<stdlib.h>  
#include<string.h>  
struct pack{  
    int v;  
    int w;  
    int total;  
}bao[10];  
  
int cmp(const void *a,const void *b){  
    return(*(pack*)b).v-(*(pack*)a).v;  
}   
  
int main(){  
    int n,s,i,j;  
    int vsum,wsum,m;  
    scanf("%d",&n);  
    while(n--){  
        memset(bao,0,sizeof(bao));   //排序   
        scanf("%d%d",&s,&m);  
        for(i=0;i<s;i++){  
            scanf("%d%d",&bao[i].v,&bao[i].w);  
            bao[i].total = bao[i].w*bao[i].v;  
        }//计算每个物品总价值  
        qsort(bao,10,sizeof(bao[0]),cmp);  
          
        wsum = 0; vsum = 0;  
        for(i=0;i<s;i++){  
            if(m>=(wsum+bao[i].w)){    //整放物品   
                vsum+=bao[i].total;  
                wsum+=bao[i].w;  
            }  
            else if(m<(wsum+bao[i].w)&&m>=wsum){   //不能整放 ,就分割放   
                vsum+=(m-wsum)*bao[i].v;  
                break;  
            }  
        }   
        printf("%d\n",vsum);  
    }  
    return 0;  
}  

Dinner

时间限制:
100 ms  |  内存限制:
65535 KB 难度:
1

描述
Little A is one member of ACM team. He had just won the gold in World Final. To celebrate, he decided to invite all to have one meal. As bowl, knife and other tableware is not enough in the kitchen, Little A goes to take backup tableware in warehouse. There are many boxes in warehouse, one box contains only one thing, and each box is marked by the name of things inside it. For example, if “basketball” is written on the box, which means the box contains only basketball. With these marks, Little A wants to find out the tableware easily. So, the problem for you is to help him, find out all the tableware from all boxes in the warehouse.

输入
There are many test cases. Each case contains one line, and one integer N at the first, N indicates that there are N boxes in the warehouse. Then N strings follow, each string is one name written on the box.
输出
For each test of the input, output all the name of tableware.
样例输入
3 basketball fork chopsticks
2 bowl letter
样例输出
fork chopsticks
bowl
提示
The tableware only contains: bowl, knife, fork and chopsticks.
来源
辽宁省10年省赛
上传者
ACM_李如兵
01.#include<stdio.h>    
02.#include<string.h>    
03.int main()    
04.{    
05.    int n;    
06.    int i;//循环变量     
07.    int t;//控制空格变量     
08.    int a[1010];    
09.    char s[1010][20];    
10.    while(scanf("%d",&n)!=EOF)    
11.    {    
12.        for(i=0;i<n;i++)    
13.        {    
14.            scanf("%s",s[i]);    
15.            a[i]=0;    
16.            if(strcmp(s[i],"fork")==0||strcmp(s[i],"bowl")==0||strcmp(s[i],"knife")==0||strcmp(s[i],"chopsticks")==0)    
17.            {    
18.                a[i]=1;    
19.            }    
20.        }    
21.        t=0;    
22.        for(i=0;i<n;i++)    
23.        {    
24.            if(a[i]==1)    
25.            {    
26.                if(t>0)    
27.                {    
28.                    printf(" ");    
29.                }    
30.                printf("%s",s[i]);    
31.                t++;    
32.            }    
33.        }    
34.        printf("\n");    
35.    }    
36.    return 0;    
37.} 

推桌子

时间限制:
1000 ms  |  内存限制:
65535 KB 难度:
3

描述
The famous ACM (Advanced Computer Maker) Company has rented a floor of a building whose shape is in the following figure. 

《NYOJ 贪心算法题目汇总(一)》

The floor has 200 rooms each on the north side and south side along the corridor. Recently the Company made a plan to reform its system. The reform includes moving a lot of tables between rooms. Because the corridor is narrow and all the tables are big, only one table can pass through the corridor. Some plan is needed to make the moving efficient. The manager figured out the following plan: Moving a table from a room to another room can be done within 10 minutes. When moving a table from room i to room j, the part of the corridor between the front of room i and the front of room j is used. So, during each 10 minutes, several moving between two rooms not sharing the same part of the corridor will be done simultaneously. To make it clear the manager illustrated the possible cases and impossible cases of simultaneous moving. 

《NYOJ 贪心算法题目汇总(一)》

For each room, at most one table will be either moved in or moved out. Now, the manager seeks out a method to minimize the time to move all the tables. Your job is to write a program to solve the manager’s problem.

输入
The input consists of T test cases. The number of test cases ) (T is given in the first line of the input file. Each test case begins with a line containing an integer N , 1 <= N <= 200, that represents the number of tables to move. 

Each of the following N lines contains two positive integers s and t, representing that a table is to move from room number s to room number t each room number appears at most once in the N lines). From the 3 + N -rd 

line, the remaining test cases are listed in the same manner as above.

输出
The output should contain the minimum time in minutes to complete the moving, one per line.
样例输入
3 
4 
10 20 
30 40 
50 60 
70 80 
2 
1 3 
2 200 
3 
10 100 
20 80 
30 50
样例输出
10
20
30
上传者
苗栋栋

#include <stdio.h>
#include <string.h>
int move[201];
int main()
{
  int T,i,j,table,ans,from,to,tmp;
  scanf("%d",&T);
  while(T--)
     {
        scanf("%d",&table);
        memset(move,0,sizeof(move));
        for(j = 0 ; j < table ; ++j)
        {
           scanf("%d %d",&from,&to);
           from = (from+1)/2;
           to = (to +1)/2;//缩减1—200
          if(from > to)//from<=to
          {
            tmp = from ;
            from = to ;
            to = tmp;
          }
           for(i = from ; i <= to ; ++i)
           ++move[i];//记录每房间区段move次数,即两from和to区间相交时,加1
        }
         ans = 0;
         for(i =1 ;i <= 200 ; ++i)
           if(move[i] > ans)
                    ans = move[i];
         printf("%d\n",ans*10);
     }
  return 0;

}

心急的C小加

时间限制:
1000 ms  |  内存限制:
65535 KB 难度:
4

描述

C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的时间,如果第i+1个木棒的重量和长度都大于等于第i个处理的木棒,那么将不会耗费时间,否则需要消耗一个单位的时间。因为急着去约会,C小加想在最短的时间内把木棒处理完,你能告诉他应该怎样做吗?

输入
第一行是一个整数T(1<T<1500),表示输入数据一共有T组。

每组测试数据的第一行是一个整数N(1<=N<=5000),表示有N个木棒。接下来的一行分别输入N个木棒的L,W(0 < L ,W <= 10000),用一个空格隔开,分别表示木棒的长度和质量。

输出
处理这些木棒的最短时间。
样例输入
3 
5 
4 9 5 2 2 1 3 5 1 4 
3 
2 2 1 1 2 2 
3 
1 3 2 2 3 1 
样例输出
2
1
3
来源
POJ改编
上传者
陈玉
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct mb
{
    int len;
    int weight;
}w[10001];
bool cmp(mb x,mb y) //排序
{
    if(x.len<y.len)  return true;  //升序
    if(x.len==y.len&&x.weight<y.weight)  return true;
    return false;
}
int main()
{
    int s,n,i,j,count,t;
    scanf("%d",&s);
    while(s--)
    {
        count=0;
        scanf("%d",&n);
        for(i=0;i<=n-1;i++)
        {
            scanf("%d %d",&w[i].len,&w[i].weight);
        }
        sort(w,w+n,cmp);
        for(i=0;i<=n-1;i++)
        {
            if(w[i].weight!=0) //数未出现过
            {
                t=w[i].weight;
                count++;  //开启一单位
                for(j=i+1;j<=n-1;j++)
                {
                    if(w[j].weight>=t)
                    {
                        t=w[j].weight;
                        w[j].weight=0;
                    }
                }
             }
         }
         printf("%d\n",count);
    }
    return 0;
}

//贪心算法 题目总结
一、喷水装置(一) 
排序,选半径大的依次相加直到>=20,局部最优——整体最优
二、喷水装置(二)
与(一)不同的是,装置的位置是固定的的,区间问题
三、会场时间安排 
对结束时间排序,尽量选择结束时间早的。局部最优——整体最优
四、过河问题
四人一组局部最优,整体最优
五、独木舟上的旅行
先把各个人的体重排序,然后计算最重的人和最轻的  
人能否同乘一条舟,如果不能,则最重的人就要单独  
乘坐一条舟,再求最轻的和第二重的人的和,依次比较。
六、阶乘之和
每一步选择最大,整体解
七、背包问题
可分割,每一次单位价值最大的,以此类推
八、Dinner
九、推桌子
类似会场安排或拦截导弹
十、心急的C小加
 类似拦截导弹 
    原文作者:贪心算法
    原文地址: https://blog.csdn.net/liujiuxiaoshitou/article/details/69728714
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞