首页 > 其他分享 >CSP模拟51联测13 B.狗

CSP模拟51联测13 B.狗

时间:2023-10-10 19:23:33浏览次数:33  
标签:13 51 样例 狗狗 联测 CSP

CSP模拟51联测13 B.狗

目录

题目大意

题目描述

小G养了很多狗。

小G一共有 \(n\times n\) 条狗,在一个矩阵上。小G想让狗狗交朋友,一条狗狗最多只能交一个朋友,不必所有狗狗都有朋友。但是狗狗交朋友有要求,具体的,第 \(i\) 行第 \(j\) 列的狗有两个值 \(d_{i,j}\in\{\texttt{U},\texttt{D},\texttt{L},\texttt{R}\}\) 表示它只能和上/下/左/右的狗狗交朋友,如果成功交友能得到 \(a_{i,j}\) 的喜悦值。一个交友方案的价值就是所有有朋友的狗狗的喜悦值之和。

小G想知道所有交友方案的价值和,由于这个数可能很大,请对 \(998244353\) 取模并告诉小G。

朋友关系是双向的,两条狗互相交朋友需要两个d都满足,上下左右不必相邻

上下左右是指正上/正下/正左/正右,也就是要在同一行同一列

输入格式

第一行一个整数 \(n\)。

接下来 \(n\) 行每行一个长度为 \(n\) 的字符串,第 \(i\) 行 \(j\) 列的字符表示 \(d_{i,j}\)。

接下来 \(n\) 行每行 \(n\) 个数字,第 \(i\) 行第 \(j\) 个表示 \(a_{i,j}\)。

输出格式

一行一个整数表示对 \(998244353\) 取模的结果。

样例

样例 1

input
4
RRRD
RULL
DULU
URUL
1 2 2 2 
1 2 2 1 
2 1 2 1 
2 2 2 1
output
160

思路

观察发现 每一行和每一列都是 相互独立

我们考虑每一行上 \(L , R\) 的的情况

设 \(f_{i , j},g_{i , j}\) 分别为前 \(i\) 个 ,想选若干个 \(R\) ,还有 \(j\) 个 \(R\) 要选的方案数和价值和

1、如果当前不选那么:

\[f_{i , j} += f_{i- 1 , j} \newline g_{i , j} += g_{i - 1 , j} \]

如果当前是 \(L\) 并且选那么:

\[f_{i , j - 1} += f_{i - 1 , j } * j \newline g_{i , j - 1} += g_{i - 1 , j} + f_{i - 1 , j} * j * a_i \]

如果当前是 \(R\) 并且选那么 :

\[f _{i , j + 1} += f_{i- 1 , j} \newline g_{i , j + 1} += g_{i - 1 , j} + f_{i - 1 , j} * a_i \]

其实每一列上 \(U , D\) 的情况差不多,所以最后复杂度 \(O(n ^3)\)

#include <bits/stdc++.h>
#define fu(x , y , z) for(int x = y ; x <= z ; x ++)
#define LL long long
using namespace std;
const LL mod = 998244353;
const int N = 505;
int n , m , cnt , flg[N];
LL f[N][N] , g[N][N] , p[N << 1] , q[N << 1] , mp[N][N] , a[N];
char s[N][N];
void solve () {
    memset (f , 0 , sizeof (f));
    memset (g , 0 , sizeof (g));
    f[0][0] = 1;
    fu (i , 1 , m) {
        fu (j , 0 , m) {
            f[i][j] = (f[i][j] + f[i - 1][j]) % mod;
            g[i][j] = (g[i][j] + g[i - 1][j]) % mod;
            if (!flg[i]) {
                f[i][j - 1] = (f[i][j - 1] + f[i - 1][j] * j % mod) % mod;
                g[i][j - 1] = (g[i][j - 1] + (g[i - 1][j] * j % mod + f[i - 1][j] * j % mod * a[i] % mod) % mod) % mod;
            }
            else {
                f[i][j + 1] = (f[i][j + 1] + f[i - 1][j]) % mod;
                g[i][j + 1] = ((g[i][j + 1] + g[i - 1][j]) % mod + f[i - 1][j] * a[i] % mod) % mod;
            }
        }
    }
    p[++cnt] = g[m][0];
    q[cnt] = f[m][0];
}
int main () {
    char c;
    scanf ("%d" , &n);
    fu (i , 1 , n) {
        fu (j , 1 , n) {
            c = getchar ();
            while (c != 'U' && c != 'D' && c != 'L' && c != 'R') c = getchar ();
            s[i][j] = c;
        }
    }
    fu (i , 1 , n)
        fu (j , 1 , n) 
            scanf ("%lld" , &mp[i][j]);
    fu (i , 1 , n) {
        m = 0;
        fu (j , 1 , n) {
            if (s[i][j] == 'L' || s[i][j] == 'R') {
                flg[++m] = (s[i][j] == 'R');
                a[m] = mp[i][j];
            }
        }
        if (m) solve ();
    }
    fu (i , 1 , n) {
        m = 0;
        fu (j , 1 , n) {
            if (s[j][i] == 'U' || s[j][i] == 'D') {
                flg[++m] = (s[j][i] == 'D');
                a[m] = mp[j][i];
            }
        }
        if (m) solve ();
    }
    LL k , ans = 0;
    fu (i , 1 , cnt) {
        k = p[i];
        fu (j , 1 , cnt) {
            if (i != j)
                k = (k * q[j]) % mod;
        }
        ans = (ans + k) % mod;
    }
    // printf ("%lld" , ans);
    cout << q[3] << " " << p[3];
    return 0;
}

标签:13,51,样例,狗狗,联测,CSP
From: https://www.cnblogs.com/2020fengziyang/p/17755498.html

相关文章

  • LY1376 [ 20231008 NOIP 模拟赛 T0 ] 递增路径
    题意\(A\),\(B\)两人轮流在一张图上移动一个点。要求这次移动的边权必须大于上次的。\(A\)希望游戏进行的轮数多,\(B\)希望游戏进行的轮数少。对于每个\(s=1,2,...,n\)作为起点,若双方都采用最优策略,游戏会进行多少轮。Sol考虑将所有边按照从大到小的顺序排序。每......
  • winget 0x8051100f错误
    解决WinGet0x8051100f错误接手了公司旧的电脑,安装的是精简版的Windows10系统,今天在准备使用winget的时候发现并没有安装。然而这台电脑精简的有点过分了,连MicrosoftStore都没有,装好WinGet之后发现执行的时候居然还会报错0x8a15000f错误。解决方案遇到错误0x8a15000f时,按照以......
  • [arc135f] Delete 1, 4, 7, ...
    F-Delete1,4,7,...设\(f(i)\)表示第一次操作后,第\(i\)个位置的数,那么\(f(i)=\lfloor\frac{3i+1}2\rfloor\)那么\(k\)次操作后,第\(i\)个位置上的数就是:\[f(f(...f(f(i))...))=f^k(i)\]设\(cnt_k\)表示\(k\)次操作后剩下的数的个数,那么显然有:\(cnt_i=\lfloor\frac{cnt_......
  • 洛谷P3300 [SDOI2013] 城市规划 题解
    [SDOI2013]城市规划题意:给你一个\(6\timesn\)的网格题,单点修改,询问区间联通块数,\(n\le10^5\)。解:看起来就很显然的一道题......线段树每个点用一个ufs维护连通性;我为了方便思考把图转成横着的了。写起来真是毒瘤......重点在于:\(\bullet\)1、建立叶节点。\(\bull......
  • k51-使用下载程序
         ......
  • k51安装与使用
             ......
  • UAV2101~UAV2105编程与仿真51MCU初学者训练
    练习001:51单片机Proteus仿真:点亮一个灯1、器件清单Proteus关键词元器件CAP固定电容CAP-ELEC电解电容AT89C51AT89C51单片机CRYSTAL晶振BUTTON复位按键RES电阻RESPACK排阻LED-YELLOW黄色发光二极管2、电路3、代码#include<reg51.h>/......
  • P8511 [Ynoi Easy Round 2021] TEST_68
    题目传送门看到异或最大值,根据套路不妨考虑\(0-1trie\)。通过\(trie\)找到异或值最大的点对\((x,y)\)。那么除了\((x,y)\)到\(1\)路径上的点之外,其他的点的答案就是\((x,y)\)的异或值。接下来考虑怎么算出这\((x,y)\)到\(1\)路径上的点的答案,可以直接暴力计算!......
  • #13
    [CCO2019]Sirtet题面首先一个连通块内的点下落的距离相同,令\(h_{i,j}\)表示\((i,j)\)所在连通块下降的距离,对于一个\((a,j)\),其中\(a>i\),\(h_{a,j}\leh_{i,j}\leh_{a,j}+i-a-1\),后面一个不等号取等当且仅当\((i,j)\)最后落在\((a'+1,j)\)。可以发现这是一个差分约......
  • Listener refused the connection with the following error: ORA-12514
    1.问题在使用OracleSQLDeveloper时,遇到以下问题:状态:失败-测试失败:Listenerrefusedtheconnectionwiththefollowingerror:ORA-12514,TNS:listenerdoesnotcurrentlyknowofservicerequestedinconnectdescriptor(CONNECTION_ID=w++gsIkwQB+f4YlRCo9RvQ==)......