HDU-1003(简单动态规划)

  • 题目链接
  • 这是一道简单的动态规划问题。题目意思即为求最大的子序列和。可将数据储存在一个数组中,然后对其进行处理。思路:数组为dp[n],即有n个数据。先假设max-sum = dp[0],并记录初始位置,末位置,和定义一个变量记录初始位置。采用一个n次的循环。循环内的操作为(如果此时循环变量为 i) : 如果dp[i-1] > 0 ,dp[i] = dp[i] + dp[i-1],(具有记录字符序列和的作用),不然的话,抛弃dp[i-1],更新起始位置。接着如果当前序列和dp[i]>max-sum,则将max-sum  = dp[i],并记录初始位置和末位置。
  • 状态转移方程:dp[i] = MAX(dp[i - 1] + dp[i], dp[i]) (n>=2)
#include      /* HDU 1003 Max Sum --- 经典DP */
#include 

int dp[100005];

int main()
{
#ifdef _LOCAL
    freopen("D:\\input.txt", "r", stdin);
#endif
    int t, n;
    int Case = 0;
    int fst, lst, maxSum; 			//记录首位位置以及最大和
    int start; 						//start是用于记录中间变化的起点的
    scanf("%d", &t);
    while (t--)
	{
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
		{
            scanf("%d", &dp[i]);
        }

        start = fst = lst = 0;
        maxSum = dp[0];
        for (int i = 1; i < n; ++i)
		{
            //dp[i] = MAX(dp[i - 1] + dp[i], dp[i]);
            //由于是从前往后更新的,可以省下一个dp数组
            if (dp[i-1] >= 0)
			{
                dp[i] = dp[i - 1] + dp[i];
            }
            else
			{
                start = i; 			//抛弃dp[i-1],则起点发生变化
            }

            if (dp[i] > maxSum)
			{
                					//若当前求得的子序列和最大,进行更新
                maxSum = dp[i];
                fst = start;
                lst = i;
            }
        }
        if (Case)
		{
            printf("\n");
        }
        printf("Case %d:\n", ++Case);
        printf("%d %d %d\n", maxSum, fst+1, lst+1);
    }

    return 0;
}


你可能感兴趣的:(【基础dp】)