SCP-bzoj-1084

项目编号:bzoj-1084

项目等级:Safe

项目描述:

  戳这里

特殊收容措施:

  分类讨论+DP。#滑稽

  预处理前缀和s[i][s]=Σa[j][s](∀j∈[1,i])(m=1时略去第二维)

  对于m=1,设计状态f[i][j]表示前i列中已选取j个矩形的最大分值。转移方程f[i][j]=max(f[i-1][j-1],max{f[k][j-1]+s[i]-s[k-1]})。

  对于m=2,设计状态f[i][j][k]表示第一行前i列中、第二行前j列中已选取k个矩形的最大分值。有三种转移方式:

  •传递性转移:max(f[i-1][j][k],f[i][j-1][k])->f[i][j][k]

  •单行转移:max(max{f[x][j][k-1]+s[i][0]-s[x-1][0]},max{f[i][x][k]+s[j][1]-s[x-1][1]})->f[i][j][k]

  •双行转移(前提:i=j):max{f[x][x][k-1]+s[i][0]-s[x-1][0]+s[j][1]-s[x-1][1]}->f[i][j][k]

  复杂度O(n4)。

附录:

 1 #include <bits/stdc++.h>
 2 #define range(i,c,o) for(register int i=(c);i<(o);++i)
 3 #define dange(i,c,o) for(register int i=(c);i>(o);--i)
 4 using namespace std;
 5 
 6 //#define __debug
 7 #ifdef __debug
 8     #define def(t) t
 9 #else
10     #define def(t) __attribute__((optimize("-O2"))) inline t
11 #endif
12 
13 // quick_io BEGIN HERE
14 def(int) getI()
15 {
16     char c=getchar(); int r=0; short s=1;
17     for(;!isdigit(c)&&c!='-';c=getchar());
18     for(;c=='-';c=getchar()) s*=-1;
19     for(;isdigit(c);c=getchar()) r=(r<<3)+(r<<1)+c-'0';
20     return s*r;
21 }
22 // quick_io END HERE
23 
24 static int N=getI(),M=getI(),K=getI();
25 int s[105][2],a[105][2],f[105][105][2];
26 def(int) solve1()
27 {
28     range(i,1,N+1) s[i][0]=s[i-1][0]+a[i][0];
29     bool cur=1;
30     range(k,0,K)
31     {
32         cur^=1;
33         range(i,1,N+1)
34         {
35             f[i][0][cur]=f[i-1][0][cur];
36             range(j,0,i) f[i][0][cur]=max(
37                 f[i][0][cur],
38                 f[j][0][cur^1]+s[i][0]-s[j][0]
39             );
40         }
41     }
42     return f[N][0][cur];
43 }
44 def(int) solve2()
45 {
46     range(i,1,N+1) range(j,0,2) s[i][j]=s[i-1][j]+a[i][j];
47     bool cur=1;
48     range(k,0,K)
49     {
50         cur^=1;
51         range(i,1,N+1) range(j,1,N+1)
52         {
53             f[i][j][cur]=max(f[i-1][j][cur],f[i][j-1][cur]);
54             range(x,0,i) f[i][j][cur]=max(
55                 f[i][j][cur],f[x][j][cur^1]+s[i][0]-s[x][0]
56             );
57             range(x,0,j) f[i][j][cur]=max(
58                 f[i][j][cur],f[i][x][cur^1]+s[j][1]-s[x][1]
59             );
60             if(i==j) range(x,0,i) f[i][j][cur]=max(
61                 f[i][j][cur],
62                 f[x][x][cur^1]+s[i][0]-s[x][0]+s[j][1]-s[x][1]
63             );
64         }
65     }
66     return f[N][N][cur];
67 }
68 
69 int main()
70 {
71     range(i,1,N+1) range(j,0,M) a[i][j]=getI();
72     return printf("%d
",M&1?solve1():solve2()),0;
73 }
View Code
原文地址:https://www.cnblogs.com/spactim/p/6921389.html