zoukankan      html  css  js  c++  java
  • 01限定串(传纸条模型)⭐

    题目描述

    我们称两个字符串是相似的,当且仅当它们的成分相同,并且组成各成分出现的数目相同。例如字符串"abbcdf"与字符串"bcfdab"就是相似的,而"abbcdf"与"abcdf"不相似,因为它们虽然成分相同,但是各成分出现的次数不同。

    牛牛本来有两个长度均为n的01字符串s,t,但是t串由于数据损坏,导致一些位置不确定到底是0还是1,不过好在,牛牛清楚的记得t串中有(cnt_{0})个0, (cnt_{1})个1

    接下来牛牛要还原损坏的t串。

    s串和t串每存在一个非空相似前缀得分(val_{0}), 每存在一个非空相似后缀得分(val_{1})

    想要知道它能够还原的t串中的最小得分与最大得分。

    输入描述:

    第一行输入五个整数n (cnt_{0}) (cnt_{1}) (val_{0}) (val{1})

    接下来输入两行表示字符串s,t,|s|=|t|=n, n<= 100

    其中,s串完全由'0','1'组成,t串完全由'0','1','?'组成。

    ?表示损坏的部分,也就是需要你还原的部分。

    输入数据保证至少存在一种合法的方案。

    输出描述:

    请输出两个整数,表示还原后的最小得分与最高得分。

    示例1

    输入

    8 6 2 1 1
    10110011
    ????????
    

    输出

    0 4
    

    说明

    可以构造01串t="00011000"达到最小得分(与s串没有相似的前缀与后缀)
    可以构造01串t="00000011"(4个相似的后缀)达到最大得分。

    示例2

    输入

    20 1 19 55 97
    11111010101111111111
    1?????1?1?1????????1
    

    输出

    566 1439
    

    说明

    最小:"11111111111111111101"
    最大:"11111111101111111111"

    示例3

    输入

    1 0 1 -999 1000
    0
    ?
    

    输出

    0 0
    

    说明

    因为限制条件为必须有1个1,所以?处只能填1

    题解

    本题给定了0和1的数量,让你如何排列才能使分数最优。

    我们先考虑问题的简单版本,如果给定字符串t全为问号,即对组成的字符串不加限制,就转变经典传纸条问题,

    即只求一条从(0,0)到(cnt0,cnt1)的路径,只能向右或向下走,使得路径上的点的权值和最大。

    显而易见的变化中的量就是坐标(x,y),用dp[x][y]来表示传到(x,y)这个坐标的时候,最大(小)的权值和

    就是普通的传纸条模型

    但是有的位置给定了你方向(t[i] != '?'), 分四种情况就行

    传统传纸条是

    for (int step = 1; step <= n; ++step)
          for (int i = 0; i <= a; ++i)
          {
                int j = step - i;
                if (判断状态是否合法) continue;
                ...
          }
    

    但是注意到后效性

    也可以直接二维枚举

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    
    const int maxn = 1e3 + 5;
    
    int n, a, b, x, y;
    int sum[maxn << 1], f1[maxn][maxn], f2[maxn][maxn];
    string s,t;
    
    int main()
    {
        cin >> n >> a >> b >> x >> y >> s >> t;
        s = " " + s; t = " " + t;
        rep(i, 1, n) sum[i] = sum[i - 1] + s[i] - '0',
    
        memset(f1, 0xcf, sizeof f1); memset(f2, 0x3f, sizeof f2);
        f1[0][0] = f2[0][0] = y * (sum[n] == b);
    
        rep (i, 0, n)
            rep (j, 0, n)
            {
                int pos = i + j;
                int cur = x * (sum[pos] == j && pos) + 
                    y * (sum[n] - sum[pos] == b - j && pos != n);
            
                if (t[pos] != '0' && j)
                {
                    f1[i][j] = max(f1[i][j], f1[i][j - 1] + cur);
                    f2[i][j] = min(f2[i][j], f2[i][j - 1] + cur); 
                }
    
                if (t[pos] != '1' && i)
                {
                    f1[i][j] = max(f1[i][j], f1[i - 1][j] + cur);
                    f2[i][j] = min(f2[i][j], f2[i - 1][j] + cur); 
                }
            }
         
        cout << f2[a][b] << " " << f1[a][b] << endl;
        return 0;
    } 
    
  • 相关阅读:
    MVC通过后台注解来添加对数据的验证。
    HTML赋值方法练习
    HTML辅助方法的练习一
    第一次接触MVC Models概念
    部分视图的理解
    使用布局文件(Layout)
    springboot基本配置及快速启动
    springboot代码测试注意事项
    logback日志的基本使用
    springboot快速创建项目框架
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/12871558.html
Copyright © 2011-2022 走看看