Codeforces 111C Petya and Spiders 문제 해결 & 코드

4067 단어 dpcodeforces
n을 주다×m의 그물칸, 그물칸마다 거미 한 마리가 있고, 거미 한 마리는 1초에 네 방향으로 한 칸씩 뛸 수 있다[그물칸에서 뛰면 안 된다](물론 뛰지 않아도 된다).1초 후 [거미 한 마리당 최대 한 번씩 행동] 그물칸에 거미가 몇 개까지 있는지 물어보세요.
사고방식: dp라dp라=dp방정식은 어떤 전이 조건이 존재할 때dp[i][sta][stb]=max(dp[i-1][stc][sta]+s[sta], dp[i][sta]][stb]) 중 i는 행수[사실 가장 큰 [2진법으로 열거할 수 없는 제곱으로 복잡하게 보낸 그 sta는 현재 행(제i행)의 상태를 나타내고, stb는 다음 행(제i+1행)의 상태를 나타내며, stc는 dp방정식에서 이전 행(i-1행)의 상태를 나타낸다.=1, 그러면 check를 옮기는 방식은 현재 줄을 검사하는 것이다. Sta와 그의 이웃을 진행하거나 연산을 하고 stb와 stc와 동시에 진행하거나 연산을 한다. 그리고 만약에 이렇게 해서 모두 1의 Stack을 얻게 된다면 이 상태는 존재할 수 있다는 것을 의미한다. 결과에 대해== 맨 뒷줄의 다음 줄이 모두 0이고 마지막 줄이 성공적으로 옮기면 모두 유효한 상태이다. 가장 작은 것을 찾아내면 된다.
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxa=1<<6;
int n,m,maxm,ans,s[maxa],dp[45][maxa][maxa];
bool check(int sta1,int sta2,int sta3)
{
    return ((sta1 | (sta1<<1) | (sta1>>1) | sta2 | sta3) & (maxm-1))==(maxm-1);
}
int cal(int x)
{
    int r=0;
    while(x)
    {
        if(x&1)r++;
        x>>=1;
    }
    return m-r;
}
int main(void)
{
    scanf("%d%d",&n,&m);
    if(m>n)swap(m,n);
    maxm=(1<<m);
    memset(dp,-1,sizeof(dp));
    for(int i=0;i<maxm;i++)
    {
        dp[0][0][i]=0;
        s[i]=cal(i);
    }
    for(int i=1;i<=n;i++)
        for(int j=0;j<maxm;j++)
            for(int k=0;k<maxm;k++)
                if(dp[i-1][j][k]!=-1)
                    for(int l=0;l<maxm;l++)
                    if(check(k,j,l))
                        dp[i][k][l]=max(dp[i][k][l],dp[i-1][j][k]+s[k]);
    for(int i=0;i<maxm;i++)
        ans=max(ans,dp[n][i][0]);
    printf("%d
"
,ans); return 0; }

좋은 웹페이지 즐겨찾기