zoukankan      html  css  js  c++  java
  • poj_2479 动态规划

    题目大意

        给定一列数,从中选择两个不相交的连续子段,求这两个连续子段和的最大值。

    题目分析

        典型的M子段和的问题,使用动态规划的方法来解决。

    f[i][j] 表示将A[1...i] 划分为j个不相交连续子串,且A[j]属于第i个子串,所能达到的最大子串和 
    g[i][j] 表示将A[1...j]划分为i个不相交连续子串,且A[j]不一定属于第i个子串,所能达到的最大子串和 
    f[i][j] = max{f[i-1][j] + A[i], g[i-1][j-1] + A[i]} 
    g[i][j] = max{g[i-1][j], f[i][j]}; 
    进行空间优化之后: 
    f[j] = max{f[j], g[j-1]} + A[i] 
    g[j - 1] = max(g[j - 1], f[j - 1]); 
    注意f和g的循环层次不同.这是因为:在外部进行到第i层循环的时候,f[i][j] = max{f[i-1][j] + A[i], g[i-1][j-1] + A[i]} 中max{}中的 f[j]和g[j-1]用的是第i-1层循环的时候的 f[j]和 g[j-1]; 若写成f[j] = max(f[j] + A[i], g[j - 1] + A[i]);g[j] = max(g[j], f[j]); 
    则本次的g[j]变成了第i次循环的g[j],而下次循环的 f[j] = max{} 中g[j-1]变成了第i次循环的g[j],而不是第i-1次循环的g[j]因此,写成 g[j-1] = max(g[j-1], f[j-1]); 使得 每次执行 
    for (j = 1; j <= m; j++){ 
    f[j] = max(f[j] + A[i], g[j-1] + A[i]); 
    g[j-1] = max(g[j-1], f[j-1]); 
    } 
    的时候, f[j]都使用第i-1层的f[j]和g[j-1],而g[j-1]使用的是第i-1层的g[j-1]和第i层的f[j]

    实现(c++)

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<string.h>
    #define MAX_LEN 50005
    #define INFINITE 1 << 30
    #define max(a, b) a > b? a:b
    long long int f[MAX_LEN];
    long long int g[MAX_LEN];
    int A[MAX_LEN];
    /*f[i][j] 表示将A[1...i] 划分为j个不相交连续子串,且A[j]属于第i个子串,所能达到的最大子串和
    g[i][j] 表示将A[1...j] 划分为i个不相交连续子串,且A[j]不一定属于第i个子串,所能达到的最大子串和
    f[i][j] = max{f[i-1][j] + A[i], g[i-1][j-1] + A[i]}
    g[i][j] = max{g[i-1][j], f[i][j]};
    进行空间优化之后:
    f[j] = max{f[j], g[j-1]} + A[i]
    g[j - 1] = max(g[j - 1], f[j - 1]);
    注意f和g的循环层次不同
    这是因为:在外部进行到第i层循环的时候,f[i][j] = max{f[i-1][j] + A[i], g[i-1][j-1] + A[i]} 中max{}中的 f[j]和g[j-1]用的是
    第i-1层循环的时候的 f[j]和 g[j-1]; 
    若写成
    f[j] = max(f[j] + A[i], g[j - 1] + A[i]);
    g[j] = max(g[j], f[j]);
    则本次的g[j]变成了第i次循环的g[j],而下次循环的 f[j] = max{} 中 g[j-1]变成了第i次循环的g[j],而不是第i-1次循环的g[j]
    因此,写成 g[j-1] = max(g[j-1], f[j-1]); 使得 每次执行
    for (j = 1; j <= m; j++){
    	f[j] = max(f[j] + A[i], g[j-1] + A[i]);
    	g[j-1] = max(g[j-1], f[j-1]);
    }
    的时候, f[j]都使用第i-1层的f[j]和g[j-1],而g[j-1]使用的是第i-1层的g[j-1]和第i层的f[j]
    */
    long long int MaxSum(int m, int n){
    	int i, j;
    	for (i = 1; i <= n; i++){
    		for (j = 1; j <= m; j++){
    			f[j] = max(f[j] + A[i], g[j-1] + A[i]);
    			g[j-1] = max(g[j-1], f[j-1]);
    		}
    		g[j - 1] = max(g[j - 1], f[j - 1]);
    	}
    	return g[m];
    }
    
    int main(){
    	int cas;
    	scanf("%d", &cas);
    	while (cas--){
    		int n;
    		scanf("%d", &n);
    
    		f[0] = g[0] = 0;
    		for	(int i = 1; i <= n; i++){
    			f[i] = g[i] = -INFINITE;
    			scanf("%d", A + i);
    		}
    		long long int max_sum = MaxSum(2, n);
    		printf("%lld
    ", max_sum);
    	}
    	return 0;
    }
    
  • 相关阅读:
    November 13th 2016 Week 47th Sunday The 1st Day
    November 12th 2016 Week 46th Saturday
    November 11th 2016 Week 46th Friday
    November 10th 2016 Week 46th Thursday
    November 9th 2016 Week 46th Wednesday
    November 8th 2016 Week 46th Tuesday
    windows 7文件共享方法
    Win7无线网络共享设置方法
    常量指针和指针常量
    如何查找局域网的外网ip
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4848416.html
Copyright © 2011-2022 走看看