zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    POJ1985 树的直径(BFS
    POJ2186 强连通分量+缩点
    AIM Tech Round 5C. Rectangles 思维
    POJ2553 汇点个数(强连通分量
    hdu6370 并查集+dfs
    UVALive 7037:The Problem Needs 3D Arrays(最大密度子图)
    POJ 3155:Hard Life(最大密度子图)
    HDU 5527:Too Rich(DFS+贪心)***
    HDU 5534:Partial Tree(完全背包)***
    Wannafly挑战赛1:Treepath(DFS统计)
  • 原文地址:https://www.cnblogs.com/liulangye/p/2651469.html
Copyright © 2011-2022 走看看