zoukankan      html  css  js  c++  java
  • [uvalive 7263] Today Is a Rainy Day(暴力,BFS,dp)

    题目链接:https://vjudge.net/problem/UVALive-7263

    题意:给两个字符串a,b,只包含1~6的数字,现在允许两种操作:1、修改某一位数字,2、修改整个串的某个数字,变成另外一个数字。问从b到a的最少操作。

    首先2操作修改的比较多,假如都能打到最优解的情况下,尽可能多的2操作一定会比较优。

    我们可以先不考虑字符串具体的变化,先考虑只有6位数的2操作的变化情况。

    以012345为起点,预处理出需要多少种2操作才可以变成一个6为的目标串。

    不必关心每一种数字有多少个,只需要关心2操作最少多少次。上述操作直接bfs就行了。

    注意做法不对称:a到b和b到a结果不一样。

    接下来枚举012345变成000000到555555的所有最小状态作为中间状态,由于1操作的存在,所以仅仅进行2操作是会多进行多余的操作的。所以实现记下:b到a的每一对数字的变化次数G,以及b中每一位数字出现的次数。

    接下来枚举中间状态:b到中间状态是通过012345到中间状态的2操作映射获得的,那么通过这次映射以及操作,可以让b中的所有字符通过映射变成对应的字符,接下来只需要记录一共有多少位没有变到a就行了。

     1 #pragma comment(linker, "/STACK:1024000000,1024000000")
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 
     5 const int maxn = 66666;
     6 const int inf = 0x7f7f7f7f;
     7 unordered_map<string, int> id;
     8 string di[maxn];
     9 int G[11][11], vis[11];
    10 int icnt, n;
    11 int dp[maxn];
    12 string a, b;
    13 queue<int> q;
    14 string itmp;
    15 
    16 void dfs(int cnt) {
    17     if(cnt == 6) {
    18         id[itmp] = icnt; di[icnt++] = itmp;
    19         return;
    20     }
    21     for(int i = 0; i < 6; i++) {
    22         string bk = itmp;
    23         itmp += (i + '0');
    24         dfs(cnt+1);
    25         itmp = bk;
    26     }
    27 }
    28 
    29 void init() {
    30     string pre, cpy;
    31     itmp.clear(); pre.clear(); id.clear(); icnt = 0;
    32     dfs(0);
    33     for(int i = 0; i < icnt; i++) dp[i] = inf;
    34     for(int i = 0; i < 6; i++) pre += (i + '0');
    35     while(!q.empty()) q.pop();
    36     q.push(id[pre]); dp[id[pre]] = 0;
    37     while(!q.empty()) {
    38         int pid = q.front(); q.pop();
    39         pre = di[pid];
    40         for(int i = 0; i < 6; i++) {
    41             for(int j = 0; j < 6; j++) {
    42                 cpy = pre;
    43                 for(int k = 0; k < 6; k++) {
    44                     if(pre[k] == i + '0') cpy[k] = j + '0';
    45                 }
    46                 int cid = id[cpy];
    47                 if(dp[cid] == inf) {
    48                     dp[cid] = dp[pid] + 1;
    49                     q.push(cid);
    50                 }
    51             }
    52         }
    53     }
    54 }
    55 
    56 int main() {
    57     // freopen("in", "r", stdin);
    58     init();
    59     while(cin >> a >> b) {
    60         memset(G, 0, sizeof(G));
    61         memset(vis, 0, sizeof(vis));
    62         n = a.length();
    63         for(int i = 0; i < n; i++) {
    64             int u = b[i] - '1';
    65             int v = a[i] - '1';
    66             G[u][v]++; vis[u]++;
    67         }
    68         int ret = inf;
    69         for(int i = 0; i < icnt; i++) {
    70             string mid = di[i];
    71             int tmp = dp[i];
    72             for(int j = 0; j < 6; j++) {
    73                 tmp += vis[j] - G[j][mid[j]-'0'];
    74             }
    75             ret = min(ret, tmp);
    76         }
    77         printf("%d
    ", ret);
    78     } 
    79     return 0;
    80 }
  • 相关阅读:
    [51nod] 1301 集合异或和
    [BZOJ] 1088: [SCOI2005]扫雷Mine
    [LUOGU] P4251 [SCOI2015]小凸玩矩阵
    8.21模拟赛
    [BZOJ] 3163: [Heoi2013]Eden的新背包问题
    [BZOJ] 1001: [BeiJing2006]狼抓兔子
    【NOIP2017提高A组冲刺11.8】好文章
    [BZOJ] 1520: [POI2006]Szk-Schools
    [BZOJ] 1877: [SDOI2009]晨跑
    day23(事务管理)
  • 原文地址:https://www.cnblogs.com/kirai/p/6825785.html
Copyright © 2011-2022 走看看