uva10559

此题请参见黑书123页。

题目的方块用color 和len表示。

用f [ i ] [ j ] [ k ] 表示把(color [ i ] , len [ i ] ), (color [ i+1 ] , len [ i+1 ] ) ,……, (color [ j-1 ] , len [ j-1 ] ),(color [ j ] , len [ j ]+k )合并的最大得分

考虑(color [ j ] , len [ j ]+k )这一段要不马上消去 要不和前面的一起消去

如果马上消去:f【i】【j-1】【0】+(len【j】+k)^2

如果和前面一起消去 那么前面有的段数可以有P位 那么得分可以有P种情况

f【i】【p】【k+len[j]】+f【p+1】【j-1】【0】;(color【p】=color【j】  i<=p<j)

所以f 【i】【j】【k】=两个的最大值. 边界条件是f【i】【i-1】【0】=0

那么为什么与前面一起消去的时候会是那个式子呢:

中间P区域相当于过度区域,那么就是I->P P>J,那么P后面的块数就应当加上当前的J的长度,因为J也算在来P的后面,然后加上从P+1到J-1后面长度为0部分

个人觉得这个算法可以理解为最长路的思路。

状态本来用dp【i】【j】表示i到j的最大值就可以了。由于这里要有中间变量。即通过中间p中转后到达j使得答案最大。那么中间P的状态有很多种。所以我们在这里就需要将其状态记录下来不然用不到子结构(或者用四层循环来模拟中间过程那么时间复杂度就高了)所以我们通过加一维状态保存中间的P状态 那么这样就可以用到最优子结构了。相当好的一道题目啊。

我跑的时间是600多MS 但是网上很多是1700++ 那是用递归的写法的 而且没有优化。但是写出来很好看很简短

递归的:http://blog.csdn.net/binwin20/article/details/7989213

我的代码中心思想和他一样 但是我是用四层循环处理的各个条件。貌似快些

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 209;
int dp[N][N][N];
int re[N];
int dfs(int l,int r,int k)
{
    if(l>r) return 0;
    if(dp[l][r][k]) return dp[l][r][k];
    dp[l][r][k] = dfs(l,r-1,0)+(1+k)*(1+k);
    for(int i=r-1;i>=l;i--)
    if(re[r]==re[i]){
        dp[l][r][k] = max(dp[l][r][k],dfs(l,i,k+1)+dfs(i+1,r-1,0));
    }
    return dp[l][r][k];
}
int main()
{
    int cas,T=1,n;
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        scanf("%d",&re[i]);
        memset(dp,0,sizeof(dp));
        printf("Case %d: %d\n",T++,dfs(1,n,0));
    }
    return 0;
}

pascal的带解析:http://hi.baidu.com/agosits/item/a84fdb2329e057e650fd87e8解释了下最优子结构怎么推的


网上还有一个神代码貌似是预处理来一遍 跑出来只有200不到

http://blog.sina.com.cn/s/blog_934b8a370100ygmo.html 可以膜拜下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值