今年暑假不AC
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 22381 Accepted Submission(s): 11732
Problem Description
“今年暑假不AC?”
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%...”
确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%...”
确实如此,世界杯来了,球迷的节日也来了,估计很多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
Author
lcy
Source
2013-11-24 15:07:46 | Accepted | 2037 | 171MS | 5088K | 1953 B | Java | 1983210400 |
import java.util.Scanner;
public class hdu2037今年暑假不AC {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner (System.in);
while(true){
int n=sc.nextInt();
if(n==0)break;
int[]a=new int[n];
int[]b=new int[n];
for(int i=0;i<n;i++){
a[i]=sc.nextInt();
b[i]=sc.nextInt();//结束时间
}
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
if(b[i]>b[j]){
int e=a[i];
a[i]=a[j];
a[j]=e;
int t=b[i];
b[i]=b[j];
b[j]=t;
}
}
}
System.out.println("排序后");
for(int i=0;i<n;i++)
System.out.println(a[i]+":"+b[i]);
System.out.println("=================");
System.out.println("打印那些活动对应的时间安排");
==============第一次做时写的一个算法==============
/*int count=1;
int min=b[0];//你要考虑只有一个的时候
for(int i=0;i<n-1;i++)//类似于冒泡排序的做法!!!
for(int j=i+1;j<n;j++)//此算法不好之处在于,没有跳转,儿有很多多余的不要的操作!!!!
if(min<=a[j]){//第2013年11月24日出现”黑色三分钟“,就是在此处!一道原题,一个小时半未能解决!!>_<.深深地祭奠!
min=b[j];
count++;
// System.out.println(a[i]+" $ "+b[i]);
break;
}*/
=============第二次做时写的一个算法====有所改进===========
int count=1;
System.out.println(a[0]+" $ "+b[0]);
for(int i=0; i<n-1;i++)//必须i<n-1,类似于冒泡排序
for(int j=i+1; j<n; j++)
if(b[i]<=a[j]){
i = j-1;//i会在改层for循环执行完毕后自身加1,所以与退回一步
count++;
System.out.println(a[j]+" $ "+b[j]);
break;
}
System.out.println(count);
}
}
}
输出结果:
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
排序后
1:3
3:4
0:7
3:8
2:9
5:10
6:12
4:14
10:15
8:18
15:19
15:20
=================
打印那些活动对应的时间安排
1 $ 3
3 $ 4
5 $ 10
10 $ 15
15 $ 19
5
上边的代码太挫!!(还是保留着,也是一个成长的过程)
在有一大堆活动时,我们最先应该选择结束时间最早的那个,以利于之后能安排更多的活动,然后,再在剩下的可选的会场中选择最可能结束时间最早的那个,依次类推,直到无法安排任何活动为止。
也就是说,每次选择时,都应该贪婪的选择结束时间最短的那个活动
贪心算法是从局部的最优解去找全局的最优解,所以很有可能就像我们一样,只看眼前不看长远的话,很有可能是会走错路的。
所以,证明贪心算法的正确性就是一件极为重要的问题。
一般,贪心算法的证明多使用反证法。
先假设存在一种方案B比我们刚才所说的方案A更好,也就是说,方案B能选出更多的活动。
现在假设方案B在第一次选择时没有选择结束时间最早的方案,则,方案B在选择第一个方案之后,剩余的方案中,起始时间一定要比方案A晚。所以方案B一定不可能比方案A选择出更多的活动如果方案B在第一次与方案A选择了相同的活动,而之后哪一次与方案A不同的话,则从此次之后,必然还会出现上面所说的情形。
故方案B一定不可能选出比方案一更多的活动。
所以,方案A就是最好的方案
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner (System.in);
while(true){
int n=sc.nextInt();
if(n==0)break;
int[]a=new int[n];
int[]b=new int[n];
for(int i=0;i<n;i++){
a[i]=sc.nextInt();
b[i]=sc.nextInt();//结束时间
}
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
if(b[i]>b[j]){
int e=a[i];
a[i]=a[j];
a[j]=e;
int t=b[i];
b[i]=b[j];
b[j]=t;
}
}
}
int count=1;
int sta = b[0];
for(int j=1; j<n; j++)
if(sta <= a[j]){
sta = b[j];
count++;
}
System.out.println(count);
}
}
}
java的类”结构体“排序:
import java.util.Arrays;
import java.util.Scanner;
public class nyoj_14_会场安排问题 {
public static void main(String[] args) {
Scanner sc=new Scanner (System.in);
int C = 1;
while(sc.hasNext()){
int n=sc.nextInt();
E [] e = new E[n];
for(int i=0;i<n;i++){
e[i] = new E();
int x=sc.nextInt();
int y=sc.nextInt();
e[i].a = x>y?y:x;
e[i].b= x>y?x:y;
}
Arrays.sort(e);//一个类似以结构体的排序时需要用Comparator而非Comparable
int count=1;
int sta = e[0].b;
for(int j=1; j<n; j++)
if(sta < e[j].a){
sta = e[j].b;
count++;
}
System.out.println("Case "+(C++)+":");
System.out.println(count+".");
}
}
}
class E implements Comparable<E>{
int a,b;
@Override
public int compareTo(E o) {
return this.b-o.b;
}
}