1 hdu 1003
最大连续子段和
i) 记录起始和终止坐标情况
dp[i] 前i个数中,以a[i]为结尾的最大连续子段和
dp[n] = max{ dp[i-1] + a[i] , a[i] }
ii)只求最大字段和
scanf("%d",&n); scanf("%d",&a); ans=t=a;
for(i=1;i
dp[i][x] i秒时在位置x,前i秒内最多接到的馅饼
dp[i][j] = max(dp[i-1][j] , max(dp[i-1][j+1] , dp[i-1][j-1])) + a[i][j] ;
初始化需要注意:dp[0][起始位置] = 0 ; dp[0][其他位置] = 负无穷
3 hdu 1087 super jumping
dp[i] 以a[i]为结尾的最大和
dp[i] = max{dp[j] , j < i && a[j] < a[i] } + a[i]
4 hdu1159 最长公共子序列
L[i][j] = L[i-1][j-1] + 1 , a[i] = b[j] ;
L[i][j] = max(L[i][j-1] , L[i-1][j]) a[i] != b[j] ;
5 hdu 1069 猴子和香蕉
重点是 : 状态的表示
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 205 ;
int dp[maxn] ;
struct block
{
int l , w , h ;
}B[maxn];
bool cmp (block A , block B)
{
if(A.l < B.l) return true ;
else if(A.l == B.l && A.w < B.w ) return true ;
else return false ;
}
int main()
{
//freopen("a.txt" ,"r" , stdin) ;
int n , x , y , z , Case = 1 , Len ;
int MaxHeight , MaxJ ;
while(scanf("%d" , &n) != EOF && n)
{
Len = 0 ;
while(n --)
{
scanf("%d%d%d" , &x , &y , &z) ;
B[Len].l = x , B[Len].w = y , B[Len].h = z , Len ++ ;
B[Len].l = x , B[Len].w = z , B[Len].h = y , Len ++ ;
B[Len].l = y , B[Len].w = x , B[Len].h = z , Len ++ ;
B[Len].l = y , B[Len].w = z , B[Len].h = x , Len ++ ;
B[Len].l = z , B[Len].w = x , B[Len].h = y , Len ++ ;
B[Len].l = z , B[Len].w = y , B[Len].h = x , Len ++ ;
}
sort(B , B + Len , cmp) ;
dp[0] = B[0].h ;
MaxHeight = dp[0] , MaxJ = 0 ;
for(int i = 1 ; i < Len ; i ++)
{
dp[i] = 0 ;
for(int j = 1 ; j < i ; j ++)
{
if(B[j].l < B[i].l && B[j].w < B[i].w)
dp[i] = max(dp[i] , dp[j]) ;
}
dp[i] += B[i].h ;
if(dp[i] > MaxHeight) { MaxHeight = dp[i] ; MaxJ = i ; }
}
printf("Case %d: maximum height = %d \n" , Case ++ , MaxHeight ) ;
}
return 0;
}
动态规划总结 : 1状态的表示 2 考虑当前状态可以由哪些(已知/前面)的状态转化而来 , 从而找出当前状态的最佳选择