1.Problem Description
给你n个整数,请按从大到小的顺序输出其中前m大的数。
Input
每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。
Output
对每组测试数据按从大到小的顺序输出前m大的数。
Sample Input
5 3
3 -35 92 213 -644
Sample Output
213 92 3
Hint
请用VC/VC++提交
Author
LL
Source
ACM暑期集训队练习赛(三)
解题思路:直接用sort会超时,个人建议用桶排序,注意不要用cin和cout(耗时间较多)。
#include<cstdio>
#include<cstring>
int Hash[1000005];
int main()
{
int n,m,x;
while(scanf("%d %d",&n,&m)!=EOF){
memset(Hash,0,sizeof(Hash));
for(int i=0;i<n;i++){
scanf("%d",&x);
Hash[x+500000]=1;
}
for(int i=1000000;m>0;i--){
if(Hash[i]){
m--;
m==0?(printf("%d\n",i-500000)):(printf("%d ",i-500000));
}
}
}
return 0;
}
2. Problem Description
Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。
Input
测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号。以下有 N
行,每行包含一条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。
Output
对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3
时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。
Sample Input
3 1
000007 James 85
000010 Amy 90
000001 Zoe 60
4 2
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 98
4 3
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 90
0 0
Sample Output
Case 1:
000001 Zoe 60
000007 James 85
000010 Amy 90
Case 2:
000010 Amy 90
000002 James 98
000007 James 85
000001 Zoe 60
Case 3:
000001 Zoe 60
000007 James 85
000002 James 90
000010 Amy 90
Source
浙大计算机研究生复试上机考试-2007年
解题思路:由于给定的数据不是很多,可以使用sort。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct stu
{
int score;
char num[7];
char name[9];
}w[100001];
bool xuehao(struct stu a,struct stu b)
{
return strcmp(a.num,b.num)<0;
}
bool xingming(struct stu a,struct stu b)
{
if(strcmp(a.name ,b.name ))
{
return strcmp(a.name ,b.name )<0;
}
else
{
return strcmp(a.num ,b.num )<0;
}
}
bool chengji(struct stu a,struct stu b)
{
if(a.score !=b.score )
return a.score <b.score ;
else
{
return strcmp(a.num ,b.num )<0;
}
}
int main()
{
int m,n,i,j;
int h=1;
while(scanf("%d%d",&m,&n)==2&&m)
{
for( i=0;i<m;i++)
{
scanf("%s%s%d",w[i].num,w[i].name,&w[i].score);
}
if(n==1)
{
sort(w,w+m,xuehao);
printf("Case %d:\n",h++);
for(i=0;i<m;i++)
printf("%s %s %d\n",w[i].num,w[i].name,w[i].score);
}
else if(n==2)
{
sort(w,w+m,xingming);
printf("Case %d:\n",h++);
for(i=0;i<m;i++)
printf("%s %s %d\n",w[i].num,w[i].name,w[i].score);
}
else
{
sort(w,w+m,chengji);
printf("Case %d:\n",h++);
for(i=0;i<m;i++)
printf("%s %s %d\n",w[i].num,w[i].name,w[i].score);
}
}
return 0;
}
3.Problem Description
Soon after he decided to design a T-shirt for our Algorithm Board on Free-City BBS, XKA found that he was trapped by all kinds of suggestions from everyone on the board. It is indeed a mission-impossible to have everybody perfectly satisfied. So he took a poll to collect people’s opinions. Here are what he obtained: N people voted for M design elements (such as the ACM-ICPC logo, big names in computer science, well-known graphs, etc.). Everyone assigned each element a number of satisfaction. However, XKA can only put K (<=M) elements into his design. He needs you to pick for him the K elements such that the total number of satisfaction is maximized.
Input
The input consists of multiple test cases. For each case, the first line contains three positive integers N, M and K where N is the number of people, M is the number of design elements, and K is the number of elements XKA will put into his design. Then N lines follow, each contains M numbers. The j-th number in the i-th line represents the i-th person’s satisfaction on the j-th element.
Output
For each test case, print in one line the indices of the K elements you would suggest XKA to take into consideration so that the total number of satisfaction is maximized. If there are more than one solutions, you must output the one with minimal indices. The indices start from 1 and must be printed in non-increasing order. There must be exactly one space between two adjacent indices, and no extra space at the end of the line.
Sample Input
3 6 4
2 2.5 5 1 3 4
5 1 3.5 2 2 2
1 1 1 1 1 10
3 3 2
1 2 3
2 3 1
3 1 2
Sample Output
6 5 3 1
2 1
Author
CHEN, Yue
Source
CYJJ’s Funny Contest #1, Killing in Seconds
解题思路:本题较简单,用sort就可以解决,但需要注意细节:当有多种方案时,优先选择序号和最小的方案,同时还要对选定的衬衫按照序号从大到小输出。
#include<cstdio>
#include<algorithm>
using namespace std;
struct w
{
int num;
double man;
}a[1001];
bool p(struct w a,struct w b)
{
if(a.man !=b.man )
return a.man >b.man ;
else
return a.num <b.num ;
}
bool p2(struct w a,struct w b)
{
return a.num >b.num ;
}
int main()
{
int m,n,k,i,j;
double h;
while(scanf("%d%d%d",&m,&n,&k)==3)
{
for(i=0;i<n;i++)
{
a[i].man =0;//先把每一件衬衫的满意度初始化为0;
}
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
scanf("%lf",&h);
a[j].num =j+1;
a[j].man +=h;
}
}
sort(a,a+n,p);//根据满意度进行从大到小排序。
sort(a,a+k,p2);//对选定的衬衫根据序号从大到小进行排序。
for(i=0;i<k;i++)
{
i==k-1?printf("%d\n",a[i].num ):printf("%d ",a[i].num );
}
}
return 0;
}
4.Problem Description
大家都知道,快速排序是不稳定的排序方法。
如果对于数组中出现的任意a[i],aj,其中a[i]==a[j],在进行排序以后a[i]一定出现在a[j]之前,则认为该排序是稳定的。
某高校招生办得到一份成绩列表,上面记录了考生名字和考生成绩。并且对其使用了某排序算法按成绩进行递减排序。现在请你判断一下该排序算法是否正确,如果正确的话,则判断该排序算法是否为稳定的。
Input
本题目包含多组输入,请处理到文件结束。
对于每组数据,第一行有一个正整数N(0<N<300),代表成绩列表中的考生数目。
接下来有N行,每一行有一个字符串代表考生名字(长度不超过50,仅包含’a’~‘z’),和一个整数代表考生分数(小于500)。其中名字和成绩用一个空格隔开。
再接下来又有N行,是上述列表经过某排序算法以后生成的一个序列。格式同上。
Output
对于每组数据,如果算法是正确并且稳定的,就在一行里面输出"Right"。如果算法是正确的但不是稳定的,就在一行里面输出"Not Stable",并且在下面输出正确稳定排序的列表,格式同输入。如果该算法是错误的,就在一行里面输出"Error",并且在下面输出正确稳定排序的列表,格式同输入。
注意,本题目不考虑该排序算法是错误的,但结果是正确的这样的意外情况。
Sample Input
3
aa 10
bb 10
cc 20
cc 20
bb 10
aa 10
3
aa 10
bb 10
cc 20
cc 20
aa 10
bb 10
3
aa 10
bb 10
cc 20
aa 10
bb 10
cc 20
Sample Output
Not Stable
cc 20
aa 10
bb 10
Right
Error
cc 20
aa 10
bb 10
Author
linle
Source
2008浙大研究生复试热身赛(2)——全真模拟
解题思路:本题较为简单,将数组进行排序后与给定的排好序的数组进行比较即可。当测试用例数据较多时,可以采用文件输入。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct w
{
int score;
char name[51];
int num;
};
bool p(struct w a,struct w b)
{
if(a.score !=b.score )
return a.score >b.score ;
else
return a.num <b.num ;
}
int main()
{
int m,i,j;
freopen("output.txt", "r", stdin);
struct w b[301],c[301];//b代表起始顺序,c代表排完后的顺序。
while(scanf("%d",&m)==1)
{
int ret=1;
for(i=0;i<m;i++)
{
scanf("%s %d",b[i].name ,&b[i].score );
b[i].num =i;
}
for(i=0;i<m;i++)
{
scanf("%s %d",c[i].name ,&c[i].score );
}
sort(b,b+m,p);
for(i=0;i<m;i++)
{
if(b[i].score !=c[i].score )//将我排好的数组与题目给定的排好的数组进行比较。
{
ret=0;
printf("Error\n");
for(j=0;j<m;j++)
printf("%s %d\n",b[j].name ,b[j].score );
break;
}
}
if(ret)
{
for(i=0;i<m;i++)
{
if(strcmp(b[i].name ,c[i].name ))
{
printf("Not Stable\n");
for(j=0;j<m;j++)
printf("%s %d\n",b[j].name ,b[j].score );
ret=0;
break;
}
}
if(ret)
printf("Right\n");
}
}
return 0;
}
5.Problem Description
FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.
The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i] a% pounds of JavaBeans if he pays F[i] a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.
Input
The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1’s. All integers are not greater than 1000.
Output
For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.
Sample Input
5 3
7 2
4 3
5 2
20 3
25 18
24 15
15 10
-1 -1
Sample Output
13.333
31.500
Author
CHEN, Yue
Source
ZJCPC2004
解题思路:本题为最简单的贪心,优先兑换兑换比最高的即可。
#include<cstdio>
#include<algorithm>
using namespace std;
struct w
{
int java;
int mao;
double bili;
}a[1001];
bool pai(struct w a,struct w b)
{
return a.bili >b.bili ;
}
int main()
{
int m,n,i;
while(scanf("%d%d",&m,&n)==2&&m!=-1)
{
double j=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&a[i].java ,&a[i].mao );
a[i].bili =(double)a[i].java /a[i].mao ;
}
sort(a,a+n,pai);
for(i=0;i<n;i++)
{
if(m>=a[i].mao )
{
j+=a[i].java ;
m-=a[i].mao ;
}
else
{
j+=a[i].bili *m;
break;
}
}
printf("%.3f\n",j);
}
return 0;
}
6.Problem Description
Here is a famous story in Chinese history.
“That was about 2300 years ago. General Tian Ji was a high official in the country Qi. He likes to play horse racing with the king and others.”
“Both of Tian and the king have three horses in different classes, namely, regular, plus, and super. The rule is to have three rounds in a match; each of the horses must be used in one round. The winner of a single round takes two hundred silver dollars from the loser.”
“Being the most powerful man in the country, the king has so nice horses that in each class his horse is better than Tian’s. As a result, each time the king takes six hundred silver dollars from Tian.”
“Tian Ji was not happy about that, until he met Sun Bin, one of the most famous generals in Chinese history. Using a little trick due to Sun, Tian Ji brought home two hundred silver dollars and such a grace in the next match.”
“It was a rather simple trick. Using his regular class horse race against the super class from the king, they will certainly lose that round. But then his plus beat the king’s regular, and his super beat the king’s plus. What a simple trick. And how do you think of Tian Ji, the high ranked official in China?”
Were Tian Ji lives in nowadays, he will certainly laugh at himself. Even more, were he sitting in the ACM contest right now, he may discover that the horse racing problem can be simply viewed as finding the maximum matching in a bipartite graph. Draw Tian’s horses on one side, and the king’s horses on the other. Whenever one of Tian’s horses can beat one from the king, we draw an edge between them, meaning we wish to establish this pair. Then, the problem of winning as many rounds as possible is just to find the maximum matching in this graph. If there are ties, the problem becomes more complicated, he needs to assign weights 0, 1, or -1 to all the possible edges, and find a maximum weighted perfect matching…
However, the horse racing problem is a very special case of bipartite matching. The graph is decided by the speed of the horses — a vertex of higher speed always beat a vertex of lower speed. In this case, the weighted bipartite matching algorithm is a too advanced tool to deal with the problem.
In this problem, you are asked to write a program to solve this special case of matching problem.
Input
The input consists of up to 50 test cases. Each case starts with a positive integer n (n <= 1000) on the first line, which is the number of horses on each side. The next n integers on the second line are the speeds of Tian’s horses. Then the next n integers on the third line are the speeds of the king’s horses. The input ends with a line that has a single 0 after the last test case.
Output
For each input case, output a line containing a single number, which is the maximum money Tian Ji will get, in silver dollars.
Sample Input
3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0
Sample Output
200
0
0
Source
2004 Asia Regional Shanghai
解题报告:关键在于田忌最慢的马,能先赢就先赢,不能赢就去消耗齐王最快的马,
然后再来考虑最快的马,能先赢就先赢,不能赢说明现在田忌和齐王最快的
马和最慢的马都相等,再来考虑把田忌最慢的马和齐王最快的马比较。
可能更小,但也可能相等。(要按顺序哦,亲。)
1.当田忌最慢的马比齐王最慢的马快,赢一场先
2.当田忌最慢的马比齐王最慢的马慢,和齐王最快的马比,输一场
3.当田忌最快的马比齐王最快的马快时,赢一场先。
4.当田忌最快的马比齐王最快的马慢时,拿最慢的马和齐王最快的马比,输一场。
5.当田忌最快的马和齐王最快的马相等时,拿最慢的马来和齐王最快的马比.
//以下是网上的证明
证明:田忌最快的马和齐王最快的马相等时拿最慢的马来和齐王最快的马比有最优解。
1)假设他们有n匹马,看n=2的时候.
a1 a2
b1 b2
因为 田忌最快的马和齐王最快的马相等
所以a1=b1,a2=b2 所以这种情况有2种比赛方式,易得这两种方式得分相等。
2)当数列a和数列b全部相等等时(a1=b1,a2=b2…an=bn),
显然最慢的马来和齐王最快的马比有最优解,可以赢n-1长,输1场,找不到更好的方法了。
3)当数列a和数列b元素全部相等时(a1=b1=a2=b2…=an=bn),无法赢也不输。
现在假设n匹马时拿最慢的马来和齐王最快的马比有最优解,
证明有n+1匹马时拿最慢的马来和齐王最快的马比也有最优解。
数列
a1 a2 a3 a4…an an+1
b1 b2 b3 b4…bn bn+1
其中ai>=ai-1,bi>=bi-1
数列a和数列b不全部相等时,拿最慢的马来和齐王最快的马比数列得到数列
(a1) a2 a3 a4…an an+1
b1 b2 b3 b4…bn (bn+1)
分4种情况讨论
1.b1=b2,an=an+1
则有
a2 a3 a4…an
b2 b3 b4…bn
其中a2>=a1,a1=b1,b1=b2,得a2>=b2(此后这种大小关系不再论述),an>=bn.
此时若a2=b1,根据归纳假设,有最优解,否则a2>根据前面“公理”论证有最优解。
当且仅当a数列,b数列元素全部相等时有an+1=b1,已证得,所以an+1>b1,
赢回最慢的马来和齐王最快的马比输的那一场。
2.b1<=b2,an=an+1
交换 b1,b2的位置,
数列
(a1) a2 a3 a4…an an+1
b2 b1 b3 b4…bn (bn+1)
此时 a2>=a1,an>=bn,
对于子表
a2 a3 a4…an
b1 b3 b4…bn
根据前面“公理”或归纳假设,有最优解。
an+1>=b2, 当且仅当b2=b3=b4=…=bn+1时有an+1=b2,这种情况,
a中其它元素<=b1,b2,b3,b4…bn,对于这部分来说,能赢 x盘(x<=n),
假如不拿最慢的马来和齐王最快的马比则拿最快的马来和齐王最快的马比,
此时平一盘,能赢x-1盘,而拿最慢的马来和齐王最快的马 比,输一盘能赢x盘,
总的来说,还是X这个数,没有亏。
3.b1=b2,an<=an+1
4.b1<=b2,an<=an+1证明方法类似,不再重复。
以证得当有n+1匹马的时候,田忌和齐王最快最慢的马速度相等时,
拿最慢的马来和齐王最快的马比有最优解,已知当n=2时成立,
所以对于n>2且为整数(废话,马的只数当然是整数)时也成立。
当n=1时…这个似乎不用讨论.
#include<algorithm>
#include<stdio.h>
using namespace std;
#define maxn 2600
int a[maxn],b[maxn];
int main()
{
int N,i,j,i1,j1,sum;
while(scanf("%d",&N)==1&&N)
{
for(i=0; i<N; i++)
scanf("%d",&a[i]);
for(i=0; i<N; i++)
scanf("%d",&b[i]);
sort(a,a+N);
sort(b,b+N);
sum=0;
for(i=0,j=N-1,i1=0,j1=N-1;i1<=j1&&i<=j;)
{
if(a[i]>b[i1])
{
i++;
i1++;
sum++;
}
else if(a[i]<b[i1])
{
i++;
j1--;
sum--;
}
else if(a[j]>b[j1])
{
j--;
j1--;
sum++;
}
else if(a[j]<b[j1])
{
i++;
j1--;
sum--;
}
//现在剩余就是最快的和最慢的都相等的情况,
//则把田忌最慢的和齐王最快的比较
else if(a[i]<b[j1])
{
i++;
j1--;
sum--;
}
else
{
i++;
j1--;
}
}
printf("%d\n",sum*200);
}
return 0;
}
7.The famous ACM (Advanced Computer Maker) Company has rented a floor of a building whose shape is in the following figure.
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.
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.
Input
The input consists of T test cases. The number of test cases ) (T is given in the first line of the input. 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 N+3-rd line, the remaining test cases are listed in the same manner as above.
Output
The output should contain the minimum time in minutes to complete the moving, one per line.
Sample Input
3
4
10 20
30 40
50 60
70 80
2
1 3
2 200
3
10 100
20 80
30 50
Sample Output
10
20
30
Source
Asia 2001, Taejon (South Korea)
解题思路:本题可以用数组元素的值代表对应的过道需要使用的次数,最后遍历数组,找出其最大值*10就是至少需要的时间。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int q[201];
int main()
{
int t,m,x,y,j;
int i;
scanf("%d",&t);
while(t--)
{
memset(q,0,sizeof(q));
int max1=0;
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d%d",&x,& y );
int da=(max(x,y)+1)/2;
int xiao=(min(x,y)+1)/2;
for(j=xiao;j<=da;j++)
q[j]++;
}
for(i=1;i<201;i++)
{
if(q[i]>max1)
max1=q[i];
}
printf("%d\n",max1*10);
}
return 0;
}
8.Problem Description
“今年暑假不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
Author
lcy
Source
ACM程序设计期末考试(2006/06/07)
解题思路:本题可先将节目根据开始时间先后进行排序,然后再遍历,每次都选择花费时间加上等待时间最短的节目来看。
#include<cstdio>
#include<algorithm>
using namespace std;
struct ww
{
int kai;int jie;
}a[1001];
bool p(struct ww d,struct ww e)
{
if(d.kai !=e.kai )
return d.kai<e.kai;
else
return d.jie <e.jie ;
}
int main()
{
int n,i,j;
while(scanf("%d",&n)==1&&n)
{
for(i=0;i<n;i++)
{
scanf("%d%d",&a[i].kai ,&a[i].jie ); //将每个节目的开始时间和结束时间存放在数组中。
}
sort(a,a+n,p);
int sum=0,time=0,t=0,min=0,time0=0;
time=a[t].kai ;
time0=a[t].kai;
while(time<=a[n-1].kai )//当当前时间超过最后一个节目的开始时间时结束循环
{
min=a[t].jie -a[t].kai ;//看最近节目需要花费的时间
for(j=t;j<n;j++)
{
if(a[j].jie -time<=min)//寻找从等待到看完耗时最短的节目
{
min=a[j].jie -time;
time0=a[j].jie;
t=j;
}
}
time=time0;
while(a[t].kai<time )//寻找距离当前时间最近的节目
{
t++;
}
time=a[t].kai ;
sum++;//收看节目数加一
}
printf("%d\n",sum);
}
return 0;
}
9.Problem Description
Given a sequence a[1],a[2],a[3]…a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).
Output
For each test case, you should output two lines. The first line is “Case #:”, # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.
Sample Input
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
Sample Output
Case 1:
14 1 4
Case 2:
7 1 6
Author
Ignatius.L
解题思路:本题为动态规划的基本题。可定义一个列宽为4的二维数组,第一列存放最优解,第二列存放初始数据,第三列存放起点,第四列存放终点。具体见代码。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
int t,sum,first,end,a[100100][4],n,ma;
cin>>t;
for(int k=1;k<=t;k++)
{
if(k>1)cout<<endl;
memset(a,0,sizeof(a));
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i][1];//1用来记录初始数据
}
a[n][0]=a[n][1];//0记录最优值
a[n][2]=n;//记录起点
a[n][3]=n;//记录终点
for(int i=n-1;i>=1;i--)
{
if((a[i][1]+a[i+1][0]>=0)&&a[i+1][0]>=0)
{
a[i][0]=a[i][1]+a[i+1][0];
a[i][2]=i;
a[i][3]=a[i+1][3];
}
else
{
a[i][0]=a[i][1];
a[i][2]=i;
a[i][3]=i;
}
}
ma=1;
for(int i=2;i<=n;i++)
{
if(a[ma][0]<a[i][0])ma=i;
}
cout<<"Case "<<k<<":"<<endl;
cout<<a[ma][0]<<" "<<a[ma][2]<<" "<<a[ma][3]<<endl;
}
return 0;
}
10.Problem Description
话说上回讲到海东集团面临内外交困,公司的元老也只剩下XHD夫妇二人了。显然,作为多年拼搏的商人,XHD不会坐以待毙的。
一天,当他正在苦思冥想解困良策的时候,突然想到了自己的传家宝,那是公司成立的时候,父亲作为贺礼送来的一个锦囊,徐父当时交代,不到万不得已的时候,不要打开它。“现在不正是最需要的时候吗?”,一边想,XHD一边找到了这个精心保管的锦囊,打开一看,里面只有一句话“杭城北麓千人洞有宝”。
二话不说,XHD拿起一个大口袋就出发了,这个千人洞他是知道的,小的时候,爸爸曾经带他来过这个隐蔽的路口,并告诉他,这是千人洞。他现在才明白爸爸当初这句话的含义。
尽管有点印象,XHD还是花了很大的精力才找到这个异常隐蔽的洞口,走进一看,几乎惊呆了,真的是眼花缭乱!不过尽管宝贝的种类不少,但是每种宝贝的量并不多,当然,每种宝贝单位体积的价格也不一样,为了挽救HDU,现在请你帮忙尽快计算出来XHD最多能带回多少价值的宝贝?(假设宝贝可以分割,分割后的价值和对应的体积成正比)
Input
输入包含多个测试实例,每个实例的第一行是两个整数v和n(v,n<100),分别表示口袋的容量和宝贝的种类,接着的n行每行包含2个整数pi和mi(0<pi,mi<10),分别表示某种宝贝的单价和对应的体积,v为0的时候结束输入。
Output
对于每个测试实例,请输出XHD最多能取回多少价值的宝贝,每个实例的输出占一行。
Sample Input
2 2
3 1
2 3
0
Sample Output
5
经过锦囊相助,HDU会脱离危机吗?
欲知后事如何,且听下回分解——
Author
lcy
Source
ACM程序设计_期末考试(时间已定!!)
解题思路:本题较为简单,优先选择单价高的宝物带回即可。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
int a[10];
int m,n,i,x,y;
while(scanf("%d",&m)==1&&m)
{
scanf("%d",&n);
int sum=0;
memset(a,0,sizeof(a));
for(i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
a[x]+=y;
}
for(i=9;i>=1;i--)
{
if(m>=a[i])
{
sum+=i*a[i];
m-=a[i];
}
else
{
sum+=i*m;
break;
}
}
printf("%d\n",sum);
}
return 0;
}
本期作业小结:
本期作业为贪婪算法专题。
贪婪算法可解决的问题通常大部分都有如下的特性:
⑴ 有一个以最优方式来解决的问题。为了构造问题的解决方案,有一个候选的对象的集合:比如不同面值的硬币。
⑵ 随着算法的进行,将积累起其它两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象。
⑶ 有一个函数来检查一个候选对象的集合是否提供了问题的解答。该函数不考虑此时的解决方法是否最优。
⑷ 还有一个函数检查是否一个候选对象的集合是可行的,也即是否可能往该集合上添加更多的候选对象以获得一个解。和上一个函数一样,此时不考虑解决方法的最优性。
⑸ 选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解。
⑹ 最后,目标函数给出解的值。
为了解决问题,需要寻找一个构成解的候选对象集合,它可以优化目标函数,贪婪算法一步一步的进行。起初,算法选出的候选对象的集合为空。接下来的每一步中,根据选择函数,算法从剩余候选对象中选出最有希望构成解的对象。如果集合中加上该对象后不可行,那么该对象就被丢弃并不再考虑;否则就加到集合里。每一次都扩充集合,并检查该集合是否构成解。如果贪婪算法正确工作,那么找到的第一个解通常是最优的。