ural 1501. Sense of Beauty

http://acm.timus.ru/problem.aspx?space=1&num=1501

dp+记忆话搜索

给你两个长度为n的0 1 串

总和有n个0 和n个1

求一个新串 要求任意前i项 0的个数 和1的个数 差不能超过1

ans[i][j] 表示要想到第一个串的第i个 第二个串的第j个时 上一个应选那个串的字符  0代表无法选 即无答案

sum[i][j] 表示对应ans   的和(-1表示‘0’   1 表示‘1’  )这样它的绝对值不超过1就行了

代码:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<string>

#include<vector>

#include<set>

#include<queue>

#include<stack>

#include<cmath>

#define LL long long



using namespace std;

const int N=1005;

int ans[N][N];

int sum[N][N];

int an[N*2];

char a[N],b[N];

int dp(int i,int j)

{

    if(ans[i][j]!=-1)

    return ans[i][j];

    if(i==0)//特殊情况

    {

        if(dp(i,j-1)&&abs(b[j-1]+sum[i][j-1])<=1)

        {ans[i][j]=2;sum[i][j]=b[j-1]+sum[i][j-1];}

        else

        ans[i][j]=0;

        return ans[i][j];

    }

    if(j==0)//特殊情况

    {

        if(dp(i-1,j)&&abs(a[i-1]+sum[i-1][j])<=1)

        {ans[i][j]=1;sum[i][j]=a[i-1]+sum[i-1][j];}

        else

        ans[i][j]=0;

        return ans[i][j];

    }

    if(dp(i,j-1)&&abs(b[j-1]+sum[i][j-1])<=1)

    {ans[i][j]=2;sum[i][j]=b[j-1]+sum[i][j-1];}

    else if(dp(i-1,j)&&abs(a[i-1]+sum[i-1][j])<=1)

    {ans[i][j]=1;sum[i][j]=a[i-1]+sum[i-1][j];}

    else

    ans[i][j]=0;

    return ans[i][j];

}

int main()

{

    //freopen("data","r",stdin);

    int n;

    while(scanf("%d",&n)!=EOF)

    {

        getchar();

        gets(a);

        gets(b);

        for(int i=0;i<n;++i)

        {

            a[i]=(a[i]=='0')? -1:1;

            b[i]=(b[i]=='0')? -1:1;

        }

        memset(ans,-1,sizeof(ans));

        ans[0][0]=3;//初始化 边界

        sum[0][0]=0;//初始化 边界

        dp(n,n);

        if(ans[n][n]==0)

        printf("Impossible\n");

        else

        {

            int l1=n,l2=n;

            for(int i=2*n-1;i>=0;--i)

            {

                an[i]=ans[l1][l2];//逐步倒退求答案

                if(ans[l1][l2]==1)

                --l1;

                else

                --l2;

            }

            for(int i=0;i<2*n;++i)

            printf("%d",an[i]);

            printf("\n");

        }



    }

    return 0;

}

  

你可能感兴趣的:(r)