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为左右塔的高度)的方法 行不通,状态之间不好比较、更新,就算能写出来 差不多也是枚举的复杂度了
状态之间的转移有些麻烦 ,加上滚动数组就更晕了。看了很多解题报告,虽然写出来了 但感觉还是没有弄透