博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 1390(消除方块(blocks))
阅读量:5066 次
发布时间:2019-06-12

本文共 2804 字,大约阅读时间需要 9 分钟。

今天中午从黑书上看到了的一道例题,动态规划——>线性模型的例1题。

看书都看不懂!

后面还是看了网上的题解,才渐渐明白......

估计我也说不清楚,所以尽力好了。

样例:

1 2 2 2 2 3 3 3 1

我们建立两个数组 :color, num.

其中,color储存的是颜色值,Num是相同颜色的个数。

例如,对上面的样例来说,我们就有:color[1..4]:=(1,2,3,1). num[1..4]:=(1,4,3,1).

我是看结题报告才懂的。所以觉得如果我没看题解,我实在是想不出这种状态来。

f[i,j,k]表示合并第i到第j组色块所得到的最大分,至于这个k,他其实是第j组之后的某一个和j组的color值相等的组的长度,现在可能说不清,慢慢讲清吧。

该状态有两种决策方式:

1.直接合并第j组,再合并i到j-1组。   此时f[i,j,k]:=f[i,j-1,0]+(num[j]+k)^2.(这个又出现了,为什么会有这个K,他是在上一层递归中加入进来的,继续看下面可能就明白了)。

2.不直接合并而是在i 和j-1 中找到某一组,并且该组的颜色与第j组颜色相同,设为p,先将p+1到j-1组合并,然后p和j因为颜色相同,自然就合成为一组了,假设合并的组还是p。

此时p的长度就为(num[p]+num[j])了,k的作用就在于此:

f[i,j,k]:=f[i,p,k+num[j]]+f[p+1,j-1,0].

为什么k会变成k+num[j]呢? 看下图:

如: 先合并 7,8,9,再合并 5,6,10,11,我们可以等效为第二张图,把5,6,10,11看成整体,由于该整体的num值不再为前者的num值,我们需要一个附加值来表示当前的num,这个附加的num就是k,显然k为当前附加值再加上等效后所需要的附加值,在这里k为2.

所以,方程就的出来了!

f[i,j,k]:=max(f[i,j-1,0]+(num[j]+k)^2,f[i,p,k+num[j]]+f[p+1,j-1,0])。(其中i<=p<j 并且 color[p]=color[j]).

answer:=f[1,n,0].

接下来就很好办了.

代码:

1 program p1390; //uses math; 2 {var 3       i,n:longint; 4 ================================================= 5 procedure mainn;} 6 var 7       i,j,k,l,m,q,m2,n,n2:longint; 8       color,num,s:array[0..200]of longint; 9       f:array[0..200,0..200,0..200]of longint;10 function max(a,b:longint):longint;11 begin12       if a>b then exit(a)13       else exit(b);14 end;15 function haha(l,r,k:longint):longint;16 var17       i,j,m,n,p:longint;18 begin19       if f[l,r,k]<>0 then exit(f[l,r,k]);20       if l=r then exit((num[r]+k)*(num[r]+k));21       f[l,r,k]:=haha(l,r-1,0)+(num[r]+k)*(num[r]+k);22       for i:=l to r-1 do23             begin24             if color[i]=color[r] then25                   begin26                   f[l,r,k]:=max(f[l,r,k],haha(l,i,num[r]+k)+haha(i+1,r-1,0));27                   end;28             end;29       haha:=f[l,r,k];30 end;31 begin32       assign(input,'p1390.in');33       reset(input);34       assign(output,'haha.out');35       rewrite(output);36       read(n2);37       for q:=1 to n2 do38       begin39       fillchar(s,sizeof(s),0);40       fillchar(f,sizeof(f),0);41       fillchar(num,sizeof(num),0);42       fillchar(color,sizeof(color),0);43       read(n);44       j:=0;45       for i:=1 to n do46             read(s[i]);47       i:=1;48       while i<=n do49             begin50             m:=s[i];51             inc(j);52             color[j]:=s[i];53             while color[j]=s[i] do54                   begin55                   inc(i);56                   inc(num[j]);57                   end;58             end;59       writeln('Case ',q,': ',haha(1,j,0));60       end;61       close(input);62       close(output);63 end.64 {==============================================}65 {begin66       readln(n);67       for i:=1 to n do68             mainn;69 end.}

 

转载于:https://www.cnblogs.com/zyxx233/archive/2012/12/11/2813749.html

你可能感兴趣的文章
Drawable 添加过滤色,改变图片颜色
查看>>
微信小程序组件通信入门及组件生命周期函数
查看>>
操作系统的实现(0)
查看>>
GridSearchCV和RandomizedSearchCV调参
查看>>
:before 和 :after
查看>>
团队作业5——测试与发布(Alpha版本)
查看>>
20165115 第二周学习总结
查看>>
【Luogu】P1896互不侵犯King(状压DP)
查看>>
node nightmare 网页自动化测试 sample
查看>>
如何简单的测试kubernetes的dns add-ons是否工作正常?
查看>>
PYTHON之DEF
查看>>
如何手工删除残留的DFS NAMESPACE
查看>>
ios日期格式转换
查看>>
【数据结构 JavaScript版】- web前端开发精品课程【红点工场】 --javascript-- 链表实现...
查看>>
有环单链表
查看>>
mysq数据库再次理解
查看>>
数据库连接jdbc理解
查看>>
三十而立,从零开始学ios开发(一):准备起航
查看>>
简单的自我介绍
查看>>
SpringMVC 返回json
查看>>