51nod-1065 最小正子段和 贪心 + 思维

Posted euzmin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod-1065 最小正子段和 贪心 + 思维相关的知识,希望对你有一定的参考价值。

 

 

N个整数组成的序列a[1],a[2],a[3],…,a[n],从中选出一个子序列(a[i],a[i+1],…a[j]),使这个子序列的和>0,并且这个和是所有和>0的子序列中最小的。
例如:4,-1,5,-2,-1,2,6,-2。-1,5,-2,-1,序列和为1,是最小的。
 
Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N+1行:N个整数
Output
输出最小正子段和。
Input示例
8
4
-1
5
-2
-1
2
6
-2
Output示例
1


解题思路:记录前缀累加和,然后排序,检查相邻的两项是否能够组成子序列,可以的话就记录该值D,记录最小的D就是结果。
排序的目的是找到前缀和最接近的数。
附ac代码:
技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <string>
 5 #include <cmath>
 6 #include <string>
 7 #include <iostream>
 8 #include <map>
 9 #include <queue>
10 const int maxn = 5 * 1e4 + 10;
11 const int inf = 0x3f3f3f3f;
12 
13 using namespace std;
14 typedef long long ll;
15 const ll mod = 1e9 + 7;
16 ll nu[maxn];
17 struct nod {
18     int r;
19     ll sum;
20 }ans[maxn];
21 bool cmp(nod a, nod b) {
22     if(a.sum < b.sum) return 1;
23     else if(a.sum == b.sum && a.r < b.r) return 1;
24     return 0;
25 }
26 int main(int argc, const char * argv[]) {
27    // int t;
28     int n;
29     scanf("%d", &n);
30     ll minn = inf;
31     for(int i = 1; i <= n; ++i) {
32         scanf("%lld", &nu[i]);
33         ans[i].sum = ans[i - 1].sum + nu[i];
34         ans[i].r = i;
35         if(nu[i] > 0)
36         minn = min(nu[i], minn);
37         if(ans[i].sum > 0)
38         minn = min(ans[i].sum, minn);
39     }
40   //  printf("%lld %lld xxxx\n", ans[2].sum, minn);
41     sort(ans + 1, ans + 1 + n, cmp);
42 
43 
44     for(int i = 2; i <= n; ++i) {
45         if(ans[i].r > ans[i - 1].r && ans[i].sum - ans[i - 1].sum > 0)
46         minn = min(minn, ans[i].sum - ans[i - 1].sum);
47         if(ans[i].r < ans[i - 1].r && ans[i - 1].sum - ans[i].sum > 0)
48         minn = min(minn, ans[i - 1].sum - ans[i].sum);
49 
50     }
51     if(minn == inf) puts("no solution");
52     else
53     printf("%lld\n", minn);
54     return 0;
55 }
View Code

 






以上是关于51nod-1065 最小正子段和 贪心 + 思维的主要内容,如果未能解决你的问题,请参考以下文章

AC日记——最小正子段和 51nod 1065

51 Nod 1065 最小正子段和(前缀和)

51Nod1065 最小正子段和

51nod 1065 最小正子段和

51nod-1065:最小正子段和(STL)

51nod1065(stl/sort)