DP一年多没碰过了,今天突然想找找感觉,找了经典的几道DP复习着敲了敲。虽然最大子矩阵,滑雪,石子合并等问题也足够经典,我还是从中找了5道最经典的DP写了这篇博文,如果您是大一,大二想踏入程序竞赛的同学可以当习题做做,如果您像我一样不是ACMer,平时项目中也很少用DP,同样可以回顾一下DP的奥妙。
1.最大连续子序列之和
给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序中元素和最大的一个, 例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和为20。
状态转移方程: sum[i]=max(sum[i-1]+a[i],a[i])
代码清单:
#include "stdio.h"
main(){
int i,sum = 0, max = 0;
int data[] = {
1,-2,3,-1,7
};
for(i = 0; i < sizeof(data)/sizeof(data[0]); i++){
sum += data[i];
if(sum > max)
max = sum;
if(sum < 0)
sum = 0;
}
printf("%d",max);
}
2.数塔问题
数塔问题 :要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
转移方程:sum[i] = max(a[左孩子] , a[右孩子]) + a[i]