The Twin Towers-DP+滚动数组
update@2011-08-04
//int flag = 0,dp[2][2001]
memset(dp,-1,sizeof(dp));//初始化 在开始构建塔之前 所有的高度差均未出现
dp[flag][0] = dp[flag^1][0] = 0;//初始化 开始构建 左右塔的高度都为0 高度差为0
for(i = 1;i <= n;i++,flag^=1){
int v;scanf("%d",&v);
for(int j = 0;j <= 2000;j++){//把v添加到每一种高度差上去
if(dp[flag^1][j] != -1){//这种高度差出现过 才更新
//未出现的高度差 如果将每一种情况枚举出来 肯定是
//有些高度差先出现 有些高度差后出现
//加在较大的一边 差值增加v
if(j+v < 2001){
dp[flag][j+v] = mymax(dp[flag^1][j],dp[flag][j+v]);
//dp[flag][]为正在更新的新状态 dp[flag^1][]为上次的状态
}
//加在较小的一边
if(v < j){//较小的边仍然会比较高的低
dp[flag][j-v] = mymax(dp[flag][j-v],dp[flag^1][j]+v);
}
else{//较小的边变得比较高的边高了
dp[flag][v-j] = mymax(dp[flag][v-j],dp[flag^1][j]+j);
}
}
}
memcpy(dp[flag^1],dp[flag],2001);//注意这里
}//结果保存在dp[flag^1][0]中
ZOJ -The Twin Towers
不好理解 = =、
首先是为什么选择高度去DP,我试了下dp[i][j] = abs(i-j);(i,j为左右塔的高度)的方法 行不通,状态之间不好比较、更新,就算能写出来 差不多也是枚举的复杂度了
状态之间的转移有些麻烦 ,加上滚动数组就更晕了。看了很多解题报告,虽然写出来了 但感觉还是没有弄透