poj 2479
学了一个星期动态规划,在网上参考别人的代码和心得的情况下终于把这个给AC了,为了自己的进步,第一次写解题日志。
2479 即是求 两个不重叠子序列的最大和。先从左边开始把从第一个数到每一个数的最大子段和求出(存在dp[i]中),代码如下:
1. for(i=0; i<n; i++){
2. scanf("%d",&s[i]);
3. sum += s[i];
4. if(sum > temp){
5. temp = sum;
6. }
7. dp[i] = temp;
8. if(sum < 0){
9. sum = 0;
10. }
11. }
再从左开始,每求一个数的最大段子和即和前面几个数的段子和的相加,(比如,现在求出了从第10个数到第7个数的最大段子和sum,然后将sum+dp[6]与ans(所求值)作比较即可),此即为所求,每求一个作一下比较,最后输出最大就OK了。时间复杂度:O(n)。
表达能力太差,说错的地方尽请各路高手指点啊,以后会多多努力。自个的代码就不粘出来丢人了。下面是我参考的一个代码:
1. #include<iostream>
2. #include<stdio.h>
3. using namespace std;
4. int main(){
5. int s[100001];
6. int dp[100001];
7. int i,j,n,temp,c,sum,ans;
8. while(cin>>n){
9. if(n == 0) return 0;
10. sum = 0;
11. temp = INT_MIN;
12. for(i=0; i<n; i++){
13. scanf("%d",&s[i]);
14. sum += s[i];
15. if(sum > temp){
16. temp = sum;
17. }
18. dp[i] = temp;
19. if(sum < 0){
20. sum = 0;
21. }
22. }
23. sum = 0;
24. ans = temp = INT_MIN;
25. for(i=n-1; i>0; i--){
26. sum += s[i];
27. if(sum > temp){
28. temp = sum;
29. }
30. if(dp[i-1] + temp > ans){
31. ans = dp[i-1] + temp;
32. }
33. if(sum < 0 ) sum = 0;
34. }
35. cout<<ans<<endl;
36. }
37. return 0;
38. }