NOIP200003 the number of squares |
Difficulty level: D; programming language: Unlimited; run time limit: 1000ms; run space limit: 51200KB; code length limit: 2000000B |
Question Description |
XYZ is one of the major programming gods of information Technology group in the high School of the first normal university, especially in the past two months, the level is rising rapidly. The teacher said that his future is immeasurable, so he has a little pride, as if there is no problem can be stumped him. This makes another programmer wjh to see, so asked for a question to test him, if within 10 minutes do not come out, after no longer so "arrogant", XYZ gladly agree. WJH requires XYZ to help Zyt solve an issue: The existing N*n grid chart (n<=10) fills some of the squares with positive integers, while the other squares put the number 0. As shown (see examples):
Zyt from point A of the upper left corner of the graph, you can walk down or right, until you reach point B in the lower right corner. On the way through, the ZYT can take the number of squares (the squares will be numbered 0 after taking away). From point A to Point B two times, you have to instruct Zyt to take the maximum number. If you get the correct maximum, he can find Mr. Yang to get the maximum number of 10 times times points, if the maximum value is wrong, to run (Zyt most afraid of this, you know). |
Input |
The first behavior is an integer N (a square chart representing n*n), followed by three integers per line, the first two representing the position, and the third number as the number placed on that position. A single line of 0 indicates the end of the input. |
Output |
Just output an integer that represents the maximum and the 2 paths that are obtained. |
Input example |
8 2 3 13 2 6 6 3 5 7 4 4 14 5 2 21 5 6 4 6 3 15 7 2 14 0 0 0 |
Output example |
67 |
Other Notes |
Data range: All positive integers are not more than 1000, too big teacher Yang not so many points to! |
The first method is that we can use the cost flow, for each point we split into two points i,i ', and from I to I ' even two arc, the capacity is 1, a fee of 0, a fee of-WI.
#include <cstdio>#include<cctype>#include<queue>#include<cstring>#include<algorithm>#defineRep (i,s,t) for (int i=s;i<=t;i++)#defineDwn (i,s,t) for (int i=s;i>=t;i--)#defineren for (int i=first[x];i!=-1;i=next[i])using namespaceStd;inlineintRead () {intx=0, f=1;CharC=GetChar (); for(;! IsDigit (c); C=getchar ())if(c=='-') f=-1; for(; IsDigit (c); C=getchar ()) x=x*Ten+c-'0'; returnx*F;}Const intmaxn= About;Const intmaxm=4010;Const intinf=1000000000;structZKW {intN,M,S,T,FIRST[MAXN],NEXT[MAXM]; intAns,cost; intVIS[MAXN],INQ[MAXN],D[MAXN]; structEdge {int from, To,flow,cost;} EDGES[MAXM]; voidInitintN) { This->n=n;m=0; memset (First,-1,sizeof(first)); } voidAddedge (int from,intTo,intCapintCost ) {Edges[m]= (Edge) { from, to,cap,cost};next[m]=first[ from];first[ from]=m++; EDGES[M]= (Edge) {to, from,0,-cost};next[m]=first[to];first[to]=m++; } intBFS () {Queue<int>Q; Rep (I,1, N) d[i]=INF; D[t]=0; inq[t]=1; Q.push (t); while(!P.empty ()) { intX=q.front (); Q.pop (); inq[x]=0; ren {Edge& e=edges[i^1]; if(E.flow&&d[e. from]>d[x]+e.cost) {d[e. from]=d[x]+E.cost; if(!inq[e. from]) inq[e. from]=1, Q.push (E. from); }}} rep (I,0, M-1) Edges[i].cost+=d[edges[i].to]-d[edges[i]. from]; Cost+=d[s];returnd[s]!=INF; } intDFS (intXinta) {if(X==t| |! a) {ans+=cost*a;returnA;} intflow=0, f;vis[x]=1; ren {Edge& e=Edges[i]; if(e.flow&&!e.cost&&!vis[e.to]&& (f=DFS (E.to,min (A,e.flow)))) {Flow+=f;a-=F; E.flow-=f;edges[i^1].flow+=F; if(!a) Break; } } returnflow; } intSolveintSintt) {ans=cost=0; This->s=s; This->t=T; while(BFS ()) Domemset (Vis,0,sizeof(VIS)); while(DFS (S,inf)); returnans; }}sol;intn,w[ the][ the];intIdintXintYintT) {returnt*n*n+ (x1) *n+y;}intMain () {n=read (); Sol.init (n*n*2); while(1) { intX=read (), Y=read (), v=read (); if(!x) Break; W[x][y]=v; } Rep (I,1, N) Rep (J,1, N) {Sol. Addedge (ID (i,j,0), ID (i,j,1),1,-W[i][j]); Sol. Addedge (ID (i,j,0), ID (i,j,1),1,0); if(i+1<=n) Sol. Addedge (ID (i,j,1), ID (i+1J0),1,0); if(j+1<=n) Sol. Addedge (ID (i,j,1), ID (i,j+1,0),1,0); } printf ("%d\n",-sol.solve (ID (1,1,0), ID (n,n,1))); return 0;}
View Code
The second method is that we use DP. Consider a person to walk two times the equivalent of two people go at the same time, set F[x1][y1][x2][y2] said the first person to go (x1,y1), the second person to go to (X2,y2) the greatest benefit.
When transferring, enumerate where the last two people were, and add the benefit of this step: F[x1][y1][x2][y2]=max (f[x1-1][y1][x2-1][y2],f[x1][y1-1][x2][y2-1],f[x1-1][y1][x2][ Y2-1],f[x1][y1-1][x2-1][y2]) +w[x1][y1]+ (x1!=x2| | Y1!=Y2) *w[x2][y2]. Time Complexity of O (n^4)
Note that the time complexity can be optimized to O (n^3) because the X1+Y1 constant equals X2+y2.
#include <cstdio>#include<cctype>#include<queue>#include<cstring>#include<algorithm>#defineRep (i,s,t) for (int i=s;i<=t;i++)#defineDwn (i,s,t) for (int i=s;i>=t;i--)#defineren for (int i=first[x];i!=-1;i=next[i])using namespaceStd;inlineintRead () {intx=0, f=1;CharC=GetChar (); for(;! IsDigit (c); C=getchar ())if(c=='-') f=-1; for(; IsDigit (c); C=getchar ()) x=x*Ten+c-'0'; returnx*F;}Const intmaxn= the;intN,W[MAXN][MAXN],F[MAXN][MAXN][MAXN];intMaxintAintBintCintd) {returnMax ( A, B, Max (c,d));}intdpintX1,intY1,intx2) { if(x1==1&&y1==1)returnw[1][1]; intY2=x1+y1-x2; if(x1<1|| x2<1|| x1>n| | x2>n| | y1<1|| y2<1|| y1>n| | Y2>n)return-1<< -; int& ans=F[X1][Y1][X2]; if(ans>=0)returnans; intTmp=max (DP (x1-1, y1,x2-1), DP (x1,y1-1, x2-1), DP (x1,y1-1, x2), DP (x1-1, y1,x2)); returnans=tmp+w[x1][y1]+ (x1==x2?0:1)*w[x2][y2];}intMain () {memset (F,-1,sizeof(f)); N=read (); while(1) { intX=read (), Y=read (), v=read (); if(!x) Break; W[x][y]=v; } printf ("%d\n", DP (N,N,N)); return 0;}
View Code
NOIP200003 the number of squares