Check Count (2)
Time limit:10000/5000 MS (java/others) Memory limit:65536/32768 K (java/others)
Total submission (s): 6206 Accepted Submission (s): 1975
Problem description gives you a m*n checkered checkerboard with a non-negative number in each lattice.
Take out a number of the number, so that the arbitrary two number of the lattice does not have a common edge, that is, the number of the 2 lattice is not adjacent, and the number of the maximum.
Input includes multiple test instances, each of which consists of 2 integers m,n and m*n non-negative numbers (M<=50,N<=50)
Output for each test instance, the maximum possible and
Sample INPUT3 375 15 21 75 15 28 34 70 5
Sample Output188
The first problem data range is small, the topic link: HDU 1565, the range is only 20, the direct pressure DP can be water over, the state can be saved to optimize the space, Dp[i][j] indicates the maximum value of the current state of the first J states, then there are:
$DP [I][k]=max (Dp[i][k], Dp[i-1][j]+sta_val (k)] (sta[k]&sta[j]==0) $
First question code:
#include <stdio.h> #include <bits/stdc++.h>using namespace std; #define INF 0x3f3f3f3f#define CLR (arr,val) memset (arr,val,sizeof (arr)) #define LC (x) (x<<1) #define RC (x) ((x<<1) +1) #define MID (x, y) ((x+y) >>1) typedef pair<int,int> PII;TYPEDEF Long Long ll;const double Pi=acos ( -1.0); const int N=21;const int M=17720;int pos[n ][n];int dp[n][m];int sta[m],cnt;inline bool Check (const int &x,const int &y) {return (x&y) ==0;} inline int bittonum (const bitset<n> &t,const int &l,const int &n) {int r=0; for (int i=0; i<n; ++i) if (T[i]) r+=pos[l][i]; return r;} void init (int n) {int r=1<<n; cnt=0; for (int i=0; i<r; ++i) if (check (i,i<<1)) sta[cnt++]=i; CLR (dp,0);} int main (void) {int n,i,j,k,temp; while (~SCANF ("%d", &n)) {if (!n) {puts ("0"); Continue } init (n); for (i=0; i<n; ++i) for (j=0; j<n; ++j) scanf ("%d", &pos[i][j]); bitset<n>bit; for (i=0; i<cnt; ++i) Dp[0][i]=bittonum (bit=sta[i],0,n); For (I=1, i<n; ++i) {for (j=0, j<cnt; ++j) {for (k=0; k<cnt; ++k) {if (check (Sta[j],sta[k])) {Temp=dp[i-1][j]+bi Ttonum (Bit=sta[k],i,n); if (temp>dp[i][k]) dp[i][k]=temp; }}}} int r=0; for (i=0; i<cnt; ++i) if (dp[n-1][i]>r) r=dp[n-1][i]; printf ("%d\n", R); } return 0;}
The second problem range is larger $2^{50}$ times the state number of the pre-processing memory when the estimated T, on-line check, found that the biggest flow recently learned the biggest stream, the first set of a template passed off and then again ... This write is relatively simple, should be the most simple DFS version of the maximum flow Ford-fulkerson algorithm, it is better to understand DFS until the extensible path is not found.
Build the map to pay attention to the two-point chart is not simply the odd side, even to the other side (debug a long time to find this low-level error), but choose the beginning of a black, not adjacent as white, and then black and white dyeing, how to determine whether the current grid is black or white it? Look at the value of (I+J), specific to the subscript from 0 or 1, simple point directly select the first lattice as Black can, build three rules: assuming the origin of the S is 0, the meeting point T is n*m+1. Encounter Black lattice is built a s->id[i][j] side, flow of val[i][j], in addition to the side of the legal white lattice built an edge, the flow of INF, White is id[i][j]->t side, traffic is val[i][j], Since it is clear that the maximum flow will have to build a reverse edge with an initial capacity of 0. Finally, the maximum flow of s~t is the weight of the maximum point weight independent set, and the sum minus this number is the answer, the concrete theorem and proof can Baidu
Code:
#include <stdio.h> #include <bits/stdc++.h>using namespace std; #define INF 0x3f3f3f3f#define CLR (arr,val) memset (arr,val,sizeof (arr)) #define LC (x) (x<<1) #define RC (x) ((x<<1) +1) #define MID (x, y) ((x+y) >>1) typedef pair<int,int> PII;TYPEDEF Long Long ll;const double Pi=acos ( -1.0); const int N=55;const int dir[4][2]={{1,0} , { -1,0},{0,-1},{0,1}};struct edge{int to; int NXT; int cap;}; int Val[n][n],id[n][n];edge e[n*n*12];int head[n*n],tot;bitset<n*n>vis;inline void bid_add (int s,int t,int c) {E[ Tot].cap=c; e[tot].to=t; E[tot].nxt=head[s]; head[s]=tot++; E[tot].cap=0; E[tot].to=s; E[TOT].NXT=HEAD[T]; head[t]=tot++;} void Init () {CLR (head,-1); tot=0;} int dfs (int s,int t,int f) {if (s==t) return F; Vis[s]=1; for (int i=head[s]; ~i; i=e[i].nxt) {int v=e[i].to; if (!vis[v]&&e[i].cap>0) {int D=dfs (v,t,min<int> (F,e[i].cap)); if (d>0) {E[i].cap-=d; E[i^1].cap+=d; return D; }}} return 0;} int max_flow (int s,int t) {int r=0; while (true) {vis.reset (); int F=dfs (s,t,inf); if (!f) break; R+=f; } return R;} int main (void) {int n,m,i,j,k; while (~SCANF ("%d%d", &n,&m)) {init (); int sum=0; for (i=0; i<n; ++i) {for (j=0; j<m; ++j) {scanf ("%d", &val[i][j]); SUM+=VAL[I][J]; id[i][j]=i*m+j+1; }} int s=0,t=n*m+1; For (i=0, i<n; ++i) {for (j=0; j<m; ++j) {if ((i+j) &1) Bid_add (Id[i][j],t,val[i][j]); else {bid_add (s,id[i][j],val[i][j]); for (k=0; k<4; ++k) {int ti=i+dIR[K][0]; int tj=j+dir[k][1]; if (ti>=0&&ti<n&&tj>=0&&tj<m) Bid_add (id[i][j],id[ti][tj],in F); }}}} printf ("%d\n", Sum-max_flow (s,t)); } return 0;}
HDU 1565&1569 Check Series (pressure DP or Max Stream)