【BZOJ5248】A pair of wooden chess (multi-provincial joint entrance examination 2018)-shape pressure DP/outline DP

Test address: A pair of wooden chess
Practice: This question needs to use the shape pressure DP/outline DP.
Note that the decision is only related to the current situation (i.e. the contour) and not to the previous specific decision, so we make f ( s t a t e ) for the contour line state is s t a t e When , what is the maximum score difference between the current chess player and the opponent's score.
It is observed that whenever the shape of the contour line is viewed from the bottom to the top, it is either going up or going to the right, which is a monotonous pattern. So we get a way to represent the state of the contour: looking from the bottom up, going up fills in that bit 0 , go right and fill in the 1 . because only go n + m times, so the state has at most 2 n + m one is acceptable.
Then the state transition equation is obvious, for all possible transition states n e x t , let the position that needs to play chess to move to this state is ( x , and ) ,have:
f ( s t a t e ) = max ( v a l ( x , and ) f ( n e x t ) )
in v a l ( x , and ) for the current chess player in ( x , and ) The points that can be obtained by playing chess, obviously s t a t e = ( 0...01...1 ) 2 Time f ( s t a t e ) for the answer. This way we can do this by memoized search with a time complexity of O ( 2 n + m ) .
Here is my code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf=(ll)1000000000*(ll)1000000000;
int n,m;
ll a[11][11],b[11][11],f[2000010]={0};
bool vis[2000010]={0};

ll dp(int st,bool type)
{
    if (vis[st]) return f[st];
    vis[st]=1;
    int x=n+1,y=1,last=-1,i=0,now=st;
    f[st]=-inf;
    while(now)
    {
        if (now&1)
        {
            if (last==0)
                f[st]=max(f[st],(type?a[x][y]:b[x][y])-dp(st-(1<<i)+(1<<(i-1)),!type));
            y++;
            last=1;
        }
        else x--,last=0;
        i++;now>>=1;
    }
    if (f[st]==-inf) f[st]=0;
    return f[st];
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%lld",&a[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%lld",&b[i][j]);

    int start=0;
    for(int i=1;i<=m;i++)
        start+=(1<<(n+i-1));
    dp(start,1);
    printf("%lld",f[start]);

    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324854526&siteId=291194637