hdu6078[优化递推过程] 2017多校4

/*hdu6078[优化递推过程] 2017多校4*/
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD = 998244353LL;
int T, m, n, a[2005], b[2005];
LL sum[2005][3], dp[2005][3];
void solve() {
    LL ans = 0;
    for (int i = 1; i <= n; i++) {
        LL up = 1, down = 0;
        for (int j = 1; j <= m; j++) {
            dp[j][0] = dp[j][1] = 0;
            if (b[j] == a[i]) {
                dp[j][0] = up;
                dp[j][1] = down;
                ans = (ans + up + down) % MOD;
            }
            else if (b[j] > a[i]) {
                up = (up + sum[j][1]) % MOD;
            }
            else down = (down + sum[j][0]) % MOD;
            cout<<"j: "<<j<<" up: "<<up<<" down: "<<down<<endl;
        }
        /*for (int j = 1; j <= m; j++) {
            printf("dp[%d][%d][%d]=%lld, dp[%d][%d][%d]=%lld\n", i, j, 0, dp[j][0], i, j, 1, dp[j][1]);
        }*/
        for (int j = 1; j <= m; j++) {
            sum[j][0] = (sum[j][0] + dp[j][0]) % MOD;
            sum[j][1] = (sum[j][1] + dp[j][1]) % MOD;
            //printf("sum[%d][0]=%lld, sum[%d][1]=%lld\n", j, sum[j][0], j, sum[j][1]);
        }
    }
    printf("%lld\n", ans);
}
int main() {
    scanf("%d", &T);
    while (T--) {
        memset(sum, 0, sizeof(sum));
        memset(dp, 0, sizeof(dp));
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        for (int i = 1; i <= m; i++) {
            scanf("%d", &b[i]);
        }
        solve();
    }
    return 0;
}
时间: 2024-08-07 21:31:32

hdu6078[优化递推过程] 2017多校4的相关文章

用矩阵乘法优化递推

(有关矩阵乘法的基本规则请自行搜索) 引例:求斐波那契数列的第 n 项 mod 1000000007 的值,n <= 1018. 分析:斐波那契数列的递推式为 f(n) = f(n-1)+f(n-2),直接循环求出 f(n) 的时间复杂度是 O(n),对于题目中的数据范围显然无法承受.很明显我们需要对数级别的算法. 由于 f(n) = 1*f(n-1) + 1*f(n-2) 这样的形式很类似于矩阵的乘法,所以我们可以先把这个问题复杂化一下,将递推求解 f(n) 与 f(n-1) 的过程看作是某两

矩阵快速幂优化递推总结

RT,主要总结一下矩阵的求法. 首先能用矩阵快速幂优化的递推类型是f[n]=5f[n-3]+6f[n-2]+2f[n-1]+n^2+n+8之类的 也就是说递推是线性递推且f[n-i]前面的系数是常数,可以含有与n有关的多项式,也可以含有常数的这种递推,下面总结一下矩阵的写法: 先考虑最简单的常数,我们其实可以忽略常数,因为顶多在没有常数的矩阵外面加一行一列就行了 以f[n]=2f[n-1]+6f[n-2]+5f[n-3]+n^2+n为例 先写迭代的矩阵,一般可以写成一行,右边有几项写几项 {f[

略谈矩阵乘法优化递推

1.矩阵基本概念: 矩阵大概就是二维数组存储的样子,然后每一个地方都有元素. 例如: 然后是矩阵的乘法: 矩阵的了解就到这里了 2.引入 求斐波那契数列第n项,n<=10^9. 1.通项公式: 不足: 要求n次方. 虽说n次方可以log2出解,但是精度问题值得考量. 2.矩阵快速幂:              先在考虑将A矩阵转化成B矩阵. 发现有这样一个转移矩阵. 使得 所以我们可以用矩阵解决了.即:   不过单纯这么用矩阵显然是远远不够的,因为一步一步是O(n)的,因此我们要用快速幂,如下伪

【矩阵乘法】【快速幂】【递推】斐波那契数列&amp;&amp;矩乘优化递推模板

题目大意: F[0]=0 F[1]=1 F[n+2]=F[n+1]+F[n] 求F[n] mod 104. F[n+2] F[n+1] = 1 1 1 0 * F[n+1] F[n] 记这个矩阵为A,则有: F[n+1] F[n] = An * F[1] F[0] = An * 1 0 然后可以快速幂 #include<cstdio> #include<vector> using namespace std; typedef vector<int> vec; typed

递推(二):递推法的应用

下面通过一些典型实例及其扩展来讨论递推法的应用. [例2]骨牌铺方格 在2×n的一个长方形方格中,用一种2×1的骨牌铺满方格.输入n(n<=40),输出铺放方案的总数. 例如n=3时,为2×3方格,骨牌的铺放方案有三种,如下图1所示. 图1  2×3方格的骨牌铺放方案 (1)编程思路. 设f[i]为铺满2*n方格的方案数,则有    f[i]=f[i-1]+f[i-2]. 其中,f[i-1]为铺满2*(n-1)方格的方案数(既然前面的2*(n-1)的方格已经铺满,那么最后一个只能是竖着放).f[

hdu4165(简单递推,实则卡特兰数的应用)

这道题之前自己做的时候并没有反应过来是求卡特兰数,当时是按递推来想的.后来查了下HDU4165,结果一看大标题就说是卡特兰数,自己想了想,还真是那么回事.主要还是对于卡特兰数用的不多,也就当时没立马反应过来了.下面介绍这道题我的思路,然后对卡特兰数再做一些补充. 本题题意:罐子里有N片相同的药片,开始的时候药片都是完整的一整片.然后一个每天从中任意取一片,如果该药片是完整的一整片,那么他会吃点半片,然后将剩余半片扔回罐里,如果恰好是半片,那他直接吃掉拿出来的半片.显然2N天后,他吃完全部N片药片

算法之——————递推的简单解释

1.顺推法:已知条件,逐步到结果,也叫迭代法,转转相除 2.逆推法:已知结果,推条件 步骤 1:确定迭代变量 2:建立迭代关系式 3:迭代过程的控制:1是计数型循环控制2,条件循环解决迭代次数无法确定的问题 关键:有迭代过程,循环结构 递推过程找迭代关系式,循环控制好迭代过程 顺推: 谷角猜想:编程打印出过程: 1 #include<stdio.h> 2 //#include<malloc> 3 #include<string.h> 4 int main() 5 { 6

HDU 4465 递推与double的精确性

题目大意不多说了 这里用dp[i][0] 代表取完第一个盒子后第二个盒子剩 i 个的概率,对应期望就是dp[i][0] *i dp[i][1] 就代表取完第二个盒子后第一个盒子剩 i 个的概率 dp[i][0]  =  p^(n+1) * (1-p)^(n-i) * C(2*n-i , n-i) = p^(n+1) * (1-p)^(n-i) * (2*n-i)! / (n-i)! / n! dp[i+1][0]  = p^(n+1) * (1-p)^(n-i-1) * C(2*n-i-1 ,

HDU2709 Sumsets【递推】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2709 题目大意: 将一个整数N分解成2^i相加的形式,共有多少种分法.例如:7 = 1+1+1+1+1+1+1 = 1+1+1+1+1+2 = 1+1+1+2+2 = 1+1+1+4 = 1+2+2+2 = 1+2+4,共有6种分法. 思路: 设a[n]为整数n分解成2^i相加形式的分法个数. 当n为奇数时,n-1为偶数,n = 1 + n-1,分解出一个1,再分解偶数n-1,也就是a[n-1]种