PAT甲级1007题解——贪心

题目分析:对于每一个点来说,如果选择合并入包含前一个点的序列那么只有在前一个点的序列不为负数(这里指的是包含前一个位置的数的一个连续序列的和不为负数),当前点才会将自己也加入这个子序列,否则,当前点则会以自身为起点作为子序列的开始(这里的贪心的思维是每个点尽可能的使得自己所融入的连续子序列的和一定是至少大于等于自身的,只要包含前一个点的子序列的和大于等于0则自己就会加入),我们用结构体存储数据,包括下标为i的数的值,包含该值的最大的连续子序列的和,和开始位置(结束位置就是自己i),最后遍历一遍找到最大的连续子序列的和是以哪一个数为结束的即可从该下标的结构体中获取所有的答案,我们默认下标为1的结构体为就是第一个数据,从第二个点开始遍历

 1 #include
 2 using namespace std;
 3 
 4 struct Node{
 5     int number;
 6     int sum;
 7     int start;
 8 }k[10005];
 9 
10 int main(){
11     int n;
12     while(scanf("%d", &n) != EOF){
13         for(int i = 1; i <= n; i++){
14             scanf("%d", &k[i].number);
15         }
16         k[1].start = 1;
17         k[1].sum = k[1].number;
18         for(int i = 2; i <= n; i++){
19             if(k[i-1].sum >= 0){        //只要前一个位置的选择的和大于等于0,则对于i点来说就是有利的 
20                 k[i].start = k[i-1].start;
21                 k[i].sum = k[i-1].sum + k[i].number;
22             }else{                        //否则则以自己为起点 
23                 k[i].start = i;
24                 k[i].sum = k[i].number; 
25             }
26         }
27         int ans = -1;
28         int start = 1;
29         int end = n;
30         for(int i = 1; i <= n; i++){
31             if(k[i].sum > ans){
32                 ans = k[i].sum;
33                 start = k[i].start;
34                 end = i;
35             }
36         }
37         if(ans == -1){
38             printf("0 %d %d\n", k[start].number, k[end].number);
39         }else{
40             printf("%d %d %d\n", ans, k[start].number, k[end].number);
41         }
42     }
43     return 0;
44 }

 

你可能感兴趣的:(PAT甲级1007题解——贪心)