• 【NOIP2014】子矩阵


    这题如果按暴力做只有一半分,最大时间复杂度为O(C(16,8)*C(16,8)); 很容易算出超时;

    我们可以发现如果直接dp会很难想,但是知道选哪几行去dp就很好写状态转移方程:

         dp[i][j]=min(dp[i][j],dp[k][j-1]+a[i]+b[k][i]);

    其中dp[i][j]表示 前i列里选j列的子矩阵最大分值

         a[i]表示 第i列选到的行的总差值

         b[k][i]表示选到的每一行第k列和第i列之间的差值

    我们只要枚举 行 然后dp一次,取最小值即可 这样最大时间复杂度就成了O(C(8,16)*n3);

    最后附上我弱弱的pascal代码: 

     1 var
     2   i,j,k,n,m,n1,m1,ans:longint;
     3   dp,a,f:array[0..16,0..16] of longint;
     4   hc:array[0..16,1..16,1..16] of longint;
     5   b,lc:array[0..17] of longint;
     6 function min(a,b:longint):longint;
     7  begin
     8   if a>b then min:=b
     9          else min:=a;
    10  end;
    11 procedure ddp;
    12  var
    13   i,j,k,max:longint;
    14  begin
    15   fillchar(f,sizeof(f),0);
    16   fillchar(lc,sizeof(lc),0);
    17   fillchar(dp,sizeof(dp),0);
    18   for i:=1 to m do
    19    for j:=1 to n1-1 do
    20     lc[i]:=lc[i]+abs(a[b[j+1],i]-a[b[j],i]);
    21   for i:=1 to m do
    22    for j:=i+1 to m do
    23     for k:=1 to n1 do
    24      f[i,j]:=f[i,j]+hc[b[k],i,j];
    25   for i:=1 to m do
    26    dp[i,1]:=lc[i];
    27   for i:=2 to m do
    28    for j:=2 to m1 do
    29     if i>=j then
    30               begin
    31                dp[i,j]:=maxlongint;
    32                for k:=j-1 to i-1 do
    33                 dp[i,j]:=min(dp[i,j],dp[k,j-1]+lc[i]+f[k,i]);
    34               end;
    35   for i:=m1 to m do
    36    if dp[i,m1]<ans then ans:=dp[i,m1];
    37  end;
    38 procedure jw(ii:longint);
    39  begin
    40   inc(b[ii]);
    41   if ii>=0 then
    42    if b[ii]>(n-n1+ii) then
    43                          begin
    44                           jw(ii-1);
    45                           b[ii]:=b[ii-1]+1;
    46                          end;
    47  end;
    48 begin
    49   read(n,m,n1,m1);
    50   for i:=1 to n do
    51    for j:=1 to m do
    52     begin
    53      read(a[i,j]);
    54      for k:=1 to j-1 do
    55       hc[i,k,j]:=abs(a[i,j]-a[i,k]);
    56     end;
    57   for i:=1 to n1 do
    58    b[i]:=i;
    59   ans:=100000000;
    60   while b[0]=0 do
    61    begin
    62     ddp;
    63     jw(n1);
    64    end;
    65   write(ans);
    66 end.
  • 相关阅读:
    多线程-工作组模式
    iOS端架构、基本组成与使用说明
    iOS,Core Animation--负责视图的复合功能
    Container Views
    IOS UIView 01-View开始深入 绘制像素到屏幕上
    View Programming Guide for iOS
    UI绘图与信息、样式
    iOS绘图框架CoreGraphics分析
    iOS开发系列--打造自己的“美图秀秀”
    Array与NSArray关系
  • 原文地址:https://www.cnblogs.com/WQHui/p/5869500.html
Copyright © 2020-2023  润新知