P2258-子矩阵

 1 #include <bits/stdc++.h>
 2 #define _for(i,a,b) for(int i = (a);i < b;i ++)
 3 
 4 typedef long long ll;
 5 using namespace std;
 6 inline ll read()
 7 {
 8     ll ans = 0;
 9     char ch = getchar(), last = ' ';
10     while(!isdigit(ch)) last = ch, ch = getchar();
11     while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
12     if(last == '-') ans = -ans;
13     return ans;
14 }
15 inline void write(ll x)
16 {
17     if(x < 0) x = -x, putchar('-');
18     if(x >= 10) write(x / 10);
19     putchar(x % 10 + '0');
20 }
21 int n,m,r,c;
22 int num[18][18];
23 int dp[18][18];
24 int lc[18],hc[18][18];
25 int df[20] = {0},dfend = 1;
26 int rnt = 0x3f3f3f3f;
27 void pre()
28 {
29     memset(lc,0,sizeof(lc));
30     memset(hc,0,sizeof(hc));
31     _for(i,1,r)
32         _for(j,1,m+1)
33             lc[j] += abs(num[df[i]][j]-num[df[i+1]][j]);
34     _for(i,1,m+1)
35         _for(j,i+1,m+1)
36             _for(k,1,r+1)
37                 hc[i][j] += abs(num[df[k]][i]-num[df[k]][j]);
38 }
39 
40 void pick()
41 {
42     _for(i,1,m+1)
43     {
44         _for(j,1,min(c+1,i+1))
45         {
46             if(1==j)
47                 dp[i][j] = lc[i];
48             else
49             {
50                 dp[i][j] = 0x3f3f3f3f;
51                 for(int k = j-1; k < i; k ++)
52                     dp[i][j] = min(dp[i][j],dp[k][j-1]+lc[i]+hc[k][i]);
53             }
54         }
55         if(i>=c)
56             rnt = min(rnt,dp[i][c]);
57     }
58 }
59 void dfs(int ii)
60 {
61     if(ii>n)
62     {
63         pre();
64         pick();
65         return ;
66     }
67     if(r-dfend==n-ii)
68     {
69         df[dfend++] = ii;
70         dfs(ii+1);
71         dfend --;
72         return ;
73     }
74     dfs(ii+1);
75     if(dfend<=r)
76     {
77         df[dfend++] = ii;
78         dfs(ii+1);
79         dfend --;
80     }
81 }
82 
83 void solve()
84 {
85     dfs(1);
86 }
87 
88 int main()
89 {
90     n = read(), m = read(),r = read(),c = read();
91 
92     _for(i,1,n+1)
93         _for(j,1,m+1)
94             num[i][j] = read();
95     solve();
96     write(rnt);
97     return 0;
98 }

 

posted @ 2019-08-18 18:59  Asurudo  阅读(165)  评论(0编辑  收藏  举报