取数模型与DP

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

取数模型与DP

1、数字三角形

每行取一个(下面的位置是上面的邻居),从上往下,求最大和。

样例:

输入N=5,下面是5行数字:

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

DP方程:

a[i,j]:=max{a[i+1,j], a[i+1,j+1]}+a[i,j] (1<=i,j<=n-1)

主要程序段:for i:=n-1 downto 1 do //从倒数第二行往上做。

For j:=1 to i do

If a[i+1,j]>a[i+1,j+1] then a[i,j]:=a[i,j]+ a[i+1,j]

Else a[i,j]:=a[i,j]+ a[i+1,j+1];

Writeln(a[1,1]);

2、求环形整数串的最大连续和。P1308

输入样例

6

-2 3 0 1 -48 80

输出样例

82

线形DP:

转化成环形

分两种情况:

1、如:-2 2 0 1 -48 1,显然其最大和连续子串是2 0 1,其和是3。

选的是中间的一段,这种情况直接使用上述的线形DP公式。

2、样例:-2 3 0 1 -48 80 结果82

选的是断开处的两端,要当成环处理。

怎样处理第2种情况呢?

第2种情况可以找中间连续一段最小的值,然后拿所有数的和--最小值

DP方法:在上页DP方程的基础上,

Ans=MAX(线性DP最大值, sum-线性DP最小值);

N值很大,如果超过数组能定义的范围,可以不用数组保存这N个数,

而是直接读一个数就处理一次。

3、求最长不下降序列P1194

样例:[输入] 14 {表示14个数}

13 7 9 16 38 24 37 18 44 19 21 22 63 15

[输出] 8 {长度为8}

7 9 16 18 19 21 22 63 {其中一种取法}

从前往后,每选一个数,总可以得到此时的最长序列,这一段的最长序列不会因为后面的不同取数方法而改变,故无后效性。

DP方程为:F[i]=MAX(F[1],………,F[i-1],其中所项的一项必须能与F[i]相连接)+1。

4、求两串字符的最长公共子序列

[输入样例]

A BC

B D A B

B D

C A BA

[输出样例]

4

BCBA

样例:C[4,5] 因为x[4]= y[5],所以c[4,5]=c[3,4]+1

C[5,4] 因为x[5]<> y[4],所以c[5,4]=max{c[5,3], c[4,4]}

最后输出C[7,6]的值。

用c[i,j]记录序列Xi和Yj的最长公共子序列的长度。C[i,j]的值表示:取X列的前i个字母,取y列的前j个字母得到的公共最长子序列的长度。边界:当i=0或j=0时,c[i,j]=0。

for i:=1 to length(x) do

for j:=1 to length(y) do

if x[i]=y[j] then c[i,j]:=c[i-1,j-1]+1

else if c[i-1,j]>c[i,j-1] then c[i,j]:=c[i-1,j] else c[i,j]:=c[i,j-1];5、求三串中的最长公共子串。P1338 胖男孩

var sol:array[0..100,0..100,0..100]of string[100];

sa,sb,sc:string[1la,lb,lc:integer;

procedure work;

var i,j,k:integer; max:string;

begin

for i:=1 to la do

for j:=1 to lb do

for k:=1 to lc do

begin

max:=''; sol[i,j,k]:='';

if length(sol[i-1,j,k])>length(max) then max:=sol[i-1,j,k];

if length(sol[i,j-1,k])>length(max) then max:=sol[i,j-1,k];

if length(sol[i,j,k-1])>length(max) then max:=sol[i,j,k-1];

if length(sol[i-1,j-1,k])>length(max) then max:=sol[i-1,j-1,k];

if length(sol[i-1,j,k-1])>length(max) then max:=sol[i-1,j,k-1];

if length(sol[i,j-1,k-1])>length(max) then max:=sol[i,j-1,k-1];

if (sa[i]=sb[j])and(sb[j]=sc[k])and (( length(sol[i-1,j-1,k-1]+sa[i]) ) >length(max))then max:=sol[i-1,j-1,k-1]+sa[i];

sol[i,j,k]:=max;

end;

end;

begin

readln(sa);

readln(sb);

readln(sc);

la:=length(sa);

lb:=length(sb);

lc:=length(sc);

work;

writeln(length(sol[la,lb,lc]));

end.

6、机器分配P1029

M个数N个人取,取不同的数得到的代价不同,怎样取,代价最大。

3 2 // 3个数,2个人取

1 2 3 //第一个人取1 2 3个数的代价

2 3 4 //第二个人取1 2 3个数的代价

输出:4

方案一:第一个人取2个数,代价2,第二个人取1个数,代价2,总和是4

方案二:第一个人取3个数,代价3

方案三:第一个人取1个数,代价1,第二个人取2个数,总和是4

。。。。

虽然方案很多,但最大代价和是4固定的。

用A[i,j]保存下面的N行数据。

F[i,j]表示第i个人取j台的最大价值。

能否用前面的状态来表示呢?

如F[2,3]表示2个公司分配3台的最大价值。可以用什么来表示?

F[1,0]+A[2,3]

相关文档
最新文档