ZOJ 3723 (Zhejiang University monthly competition) Pressure DP

Source: Internet
Author: User
Tags acos

A has been around for A whole day ~~~ Finally, I got rid of it.

It's really blood.

The question is very clear, it must be a pressure DP.

We can contact the POJ 1185 Artillery Position for the classic pressure DP.

The difference between the two questions is that the attack on this question can be blocked by X, and the attack scope is different.

This is the attack scope of this question.


However, the attack scope is blocked by X.

So we have to improve it in 1185.

Analysis:

POJ 1185, because it can be played across obstacles, the status of each row is the same, but the attack will be blocked, so the status of each row is different, therefore, we need to process the number of States in each row during preprocessing, save them separately, and save the number of States in each row.

Because my subscript starts from 0, I have to handle the status transfer process of rows 0th and 1st in advance. This is very easy to handle, depending on the code.


After preprocessing, it is the process of state transfer.

Variable definition:

M [I]: compress the map of each row.

St [I] [j]: Row j, status I.

Count [I] [j]: Number of I states in row j.

Num [I]: the total number of States in row I.

Dp [I] [j] [k]: The status of row I is k, and that of row I-1 is the total number of feasible states of Row j.

This question seems to be stuck in memory and must use a rolling array, because it only needs three states during the pressure, so I can open it to 3 here.

In the state transfer process, the current State is k, the previous state is j, and the last state is l.

First, determine the feasibility of k and j. First, j cannot appear above k, that is (st [j] [I-1] & st [k] [I]), and then k cannot appear in the lower left and lower right of j, k cannot appear in the left-shifted position of j and right-shifted position of j. So we can determine this (st [j] [I-1]> 1 & st [k] [I]), (st [j] [I-1] <1 & st [k] [I]). In this way, the statuses j and k are processed.

The next step is j and l. The judgment here is the same as j and k, because they are both adjacent rows. I will not talk about them here, but the same is true, the following describes how to judge the status of l and k.

Because l and k may be separated by X, we cannot directly judge whether X exists between them.

For example, to determine whether l is above k, you cannot directly (st [l] [I-2] & st [k] [I]), because if there is X between them, this status is valid.

So how can we determine it. I got stuck here yesterday. I suddenly thought this morning that we only need to determine that the l and k statuses are both 1 positions, then their I-1 line will be set to whether the position is X. To judge X, we can directly use the compressed map for judgment.

You can do this:

Int s = (st [l] [I-1] & st [k] [I]);

If (s & M [I-1]! = S)

Then it turns out that they attack each other, s & (M [I-1])! = S, it means that at least one of the locations where l and k are both 1 is not X, so this state is not feasible.

Similarly, we can determine whether the lower-left or lower-right attack of l state hits k State.

If the attack is in the lower left corner, you only need to move the l state to the left and k to determine whether X exists between them. Looking at the code, I will not explain it much. I believe it is easy to draw a picture by myself.

Similarly, the lower-right attack.

As to why the lower-left or lower-right attack between two adjacent columns does not need to be determined by X, we can think of it all at once.

Paste the following code.
 

# Include <set> # include <map> # include <stack> # include <cmath> # include <queue> # include <cstdio> # include <string> # include <vector> # include <iomanip> # include <cstring> # include <iostream> # include <algorithm> # define Max 2505 # define ll long # define PI acos (-1.0) # define inf 0x7fffffff # define LL (x) (x <1) # define bug puts ("here") # define PII pair <int, int> # define RR (x) (x <1 | 1) # Define mp (a, B) make_pair (a, B) # define mem (a, B) memset (a, B, sizeof (a) # define REP (I, s, t) for (int I = (s); I <= (t); ++ I) using namespace std; inline void RD (int & ret) {char c; do {c = getchar () ;}while (c <'0' | c> '9'); ret = c-'0 '; while (c = getchar ()> = '0' & c <= '9') ret = ret * 10 + (c-'0 ');} inline void OT (int a) {if (a> = 10) OT (a/10); putchar (a % 10 + '0');} # d Efine N 190 int n, m; char Map [1001] [15]; int M [1001]; int st [N] [1001]; int top; int Count [N] [1001]; int num [1001]; // int dp [1111] [N] [N]; int dp [3] [N] [N]; void init () {mem (M, 0); mem (st, 0); top = 0; mem (Count, 0); mem (dp, 0); mem (num, 0);} void OK () {for (int I = 0; I <n; I ++) {for (int j = 0; j <1 <m; j ++) {int d = 0; bool flag = 0; for (int k = 0; k <m; k + +) {If (j & (1 <k) {if (Map [I] [k] = 'X') {flag = 1; break ;} if (d> 2) {flag = 1; break;} d = 4;} else {if (Map [I] [k] = 'X ') {d = 0; continue;} d -- ;}} if (flag) continue; int tt = j; int nn = 0; while (tt) {nn + = tt % 2; tt/= 2;} // cout <j <endl; st [num [I] [I] = j; count [num [I] ++] [I] = nn ;}} int main () {while (cin> n> m, (n + m )) {init (); for (int I = 0; I <n; I ++) {scanf ("% s", Map [I]); for (int j = 0; j <m; j ++) {if (Map [I] [j] = 'X') M [I] + = (1 <j );} // cout <M [I] <endl;} OK (); int ans = 0; // preprocessing 0th rows for (int I = 0; I <num [0]; I ++) {if (st [I] [0] & M [0]) continue; dp [0] [0] [I] = Count [I] [0]; ans = max (ans, dp [0] [0] [I]);} // pre-process 1st rows for (int I = 0; I <num [1]; I ++) {if (st [I] [1] & M [1]) continue; for (int j = 0; J <num [0]; j ++) {if (st [j] [0] & st [I] [1]) continue; if (st [j] [0]> 1 & st [I] [1]) continue; if (st [j] [0] <1 & st [I] [1]) continue; dp [1] [j] [I] = max (dp [1] [j] [I], dp [0] [0] [j] + Count [I] [1]) ;}// status Transfer Process for (int I = 2; I <n; I ++) {for (int j = 0; j <num [I-1]; j ++) {for (int k = 0; k <num [I]; k ++) {if (M [I] & st [k] [I]) | (M [I-1] & st [j] [I-1]) | (st [j] [I-1] <1) & s T [k] [I]) | (st [j] [I-1]> 1) & st [k] [I]) continue; if (st [j] [I-1] & st [k] [I]) continue; for (int l = 0; l <num [I-2]; l ++) {if (M [I-2] & st [l] [I-2]) | (st [l] [I-2] & st [j] [I-1]) continue; if (st [l] [I-2]> 1) & st [j] [I-1]) | (st [l] [I-2] <1) & st [j] [I-1]) continue; if (! Dp [(I + 2) % 3] [l] [j]) continue; int s = (st [l] [I-2]> 2) & st [k] [I]; // lower right if (s) {s <= 1; if (s & M [I-1])! = S) continue;} s = (st [l] [I-2] <2) & st [k] [I]; // lower left if (s) {s> = 1; if (s & M [I-1])! = S) continue;} s = (st [l] [I-2]) & st [k] [I]; // above if (s) {if (s & M [I-1])! = S) continue;} dp [I % 3] [j] [k] = max (dp [I % 3] [j] [k], dp [(I + 2) % 3] [l] [j] + Count [k] [I]); ans = max (ans, dp [I % 3] [j] [k]); // bug ;}}}cout <ans <endl;} return 0 ;} # include <set> # include <map> # include <stack> # include <cmath> # include <queue> # include <cstdio> # include <string> # include <vector> # include <iomanip> # include <cstring> # include <iostream> # include <algorithm> # define Max 250 5 # define ll long # define PI acos (-1.0) # define inf 0x7fffffff # define LL (x) (x <1) # define bug puts ("here ") # define PII pair <int, int> # define RR (x) (x <1 | 1) # define mp (a, B) make_pair (a, B) # define mem (a, B) memset (a, B, sizeof (a) # define REP (I, s, t) for (int I = (s ); I <= (t); ++ I) using namespace std; inline void RD (int & ret) {char c; do {c = getchar ();} while (c <'0' | c> '9'); ret = C-'0'; while (c = getchar ()> = '0' & c <= '9 ') ret = ret * 10 + (c-'0');} inline void OT (int a) {if (a> = 10) OT (a/10 ); putchar (a % 10 + '0') ;}# define N struct int n, m; char Map [1001] [15]; int M [1001]; int st [N] [1001]; int top; int Count [N] [1001]; int num [1001]; // int dp [1111] [N] [N]; int dp [3] [N] [N]; void init () {mem (M, 0 ); mem (st, 0); top = 0; mem (Count, 0); mem (dp, 0); mem (num, 0) ;} Void OK () {for (int I = 0; I <n; I ++) {for (int j = 0; j <1 <m; j ++) {int d = 0; bool flag = 0; for (int k = 0; k <m; k ++) {if (j & (1 <k) {if (Map [I] [k] = 'X') {flag = 1; break ;} if (d> 2) {flag = 1; break;} d = 4;} else {if (Map [I] [k] = 'X ') {d = 0; continue;} d -- ;}} if (flag) continue; int tt = j; int nn = 0; while (tt) {nn + = tt % 2; tt/= 2;} // Cout <j <endl; st [num [I] [I] = j; count [num [I] ++] [I] = nn ;}} int main () {while (cin> n> m, (n + m )) {init (); for (int I = 0; I <n; I ++) {scanf ("% s", Map [I]); for (int j = 0; j <m; j ++) {if (Map [I] [j] = 'X ') M [I] + = (1 <j) ;}// cout <M [I] <endl ;} OK (); int ans = 0; // pre-process 0th rows for (int I = 0; I <num [0]; I ++) {if (st [I] [0] & M [0]) continue; dp [0] [0] [I] = Count [I] [0]; ans = max (ans, dp [0] [0] [I]);} // preprocessing 1st rows for (int I = 0; I <num [1]; I ++) {if (st [I] [1] & M [1]) continue; for (int j = 0; j <num [0]; j ++) {if (st [j] [0] & st [I] [1]) continue; if (st [j] [0]> 1 & st [I] [1]) continue; if (st [j] [0] <1 & st [I] [1]) continue; dp [1] [j] [I] = max (dp [1] [j] [I], dp [0] [0] [j] + Count [I] [1]) ;}// status Transfer Process for (int I = 2; I <n; I ++) {for (int j = 0; j <Num [I-1]; j ++) {for (int k = 0; k <num [I]; k ++) {if (M [I] & st [k] [I]) | (M [I-1] & st [j] [I-1]) | (st [j] [I-1] <1) & st [k] [I]) | (st [j] [I-1]> 1) & st [k] [I]) continue; if (st [j] [I-1] & st [k] [I]) continue; for (int l = 0; l <num [I-2]; l ++) {if (M [I-2] & st [l] [I-2]) | (st [l] [I-2] & st [j] [I-1]) continue; if (st [l] [I-2]> 1) & st [j] [I-1]) | (st [l] [I-2] <1) & st [j] [I-1]) continue; if (! Dp [(I + 2) % 3] [l] [j]) continue; int s = (st [l] [I-2]> 2) & st [k] [I]; // lower right if (s) {s <= 1; if (s & M [I-1])! = S) continue;} s = (st [l] [I-2] <2) & st [k] [I]; // lower left if (s) {s> = 1; if (s & M [I-1])! = S) continue;} s = (st [l] [I-2]) & st [k] [I]; // above if (s) {if (s & M [I-1])! = S) continue;} dp [I % 3] [j] [k] = max (dp [I % 3] [j] [k], dp [(I + 2) % 3] [l] [j] + Count [k] [I]); ans = max (ans, dp [I % 3] [j] [k]); // bug ;}}}cout <ans <endl;} return 0 ;}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.