2021 ICPC 江西省大学生程序设计竞赛(正式赛)


A.Mio visits ACGN Exhibition

思路:

首先考虑最暴力的dp,一共是思维数组f[i][j][k][l],表示走到(i,j)时,刚好经过k个0和l个1的路线数,但想都不用想肯定会爆,所以要优化,然后考虑到由于一共经历了i+j-1个格子,所以有k个0的话,1的个数就是i+j-1-k,此时可以去掉一维,但是此时还是会爆,所以我们通过背包问题的优化思想又可以去掉一维i。

之后状态方程就可以分类写成:

1.当a[ i ][ j ] == 0时,dp[ i ][ j ][ k ] = dp[ i - 1 ][ j ][ k - 1 ] + dp[ i ][ j - 1 ][ k - 1 ]
2.当a[ i ][ j ] == 1时,dp[ i ][ j ][ k ] = dp[ i - 1 ][ j ][ k ] + dp[ i ][ j - 1 ][ k ]

#include <bits/stdc++.h>

#define IOS ios::sync_with_stdio(false);cin.tie(0);

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 510, M = 1010, MOD = 998244353;
const double PI = acos(-1);

int n, m, p, q;
int g[N][N];
LL f[N][M];

int main()
{
    IOS;
    cin >> n >> m >> p >> q;
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            cin >> g[i][j];
    //f[i][j][k][l]表示走到(i,j)时,刚好经过k个0和l个1的路线数
    //由于一共经历了i+j-1个格子,所以有k个0的话,1的个数就是i+j-1-k,此时可以去掉一维
    //通过背包问题的优化思想又可以去掉一维i

    if(g[1][1] == 0)
        f[1][1] = 1;//初始化
    else
        f[1][0] = 1;

    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
        {
            if(i == 1 && j == 1)
                continue;
            if(g[i][j] == 0)
            {
                //注意此时k的枚举是从后往前来的
                for (int k = i + j - 1; k >= 1; k -- )
                    f[j][k] = (f[j][k - 1] + f[j - 1][k - 1]) % MOD;
                f[j][0] = 0;//
            }
            else 
            {
                for (int k = i + j - 1; k >= 0; k -- )
                    f[j][k] = (f[j][k] + f[j - 1][k]) % MOD;
            }
        }

    int res = 0;
    for (int i = p; i <= n + m - 1 - q; i ++ )
        res = (res + f[m][i]) % MOD;

    cout << res << endl;

    return 0;
}

H.Hearthstone So Easy

思路:

由于都采取最优策略,所以可以这么考虑:

每个回合

1:p打f了k滴血,那f可以回k滴血,那p必先疲劳死。

2:p回了k滴血,那f也可以回k滴血,那p照样先疲劳死

所以

我们考虑在第 i + 1,(i > 0) 回合 A 刚好可以击杀 B,即在第 i 回合 A 无法击杀 B。那么在第 i 回合 B
一定可以击杀 A。所以只要 A 第一回合无法击杀 B,那么 B 一定赢。
因此结论可以表示为:
1. 如果 A 第一回合被扣血死,那么 B 赢;
2. 如果 A 第一回合能打死 B,或者使 B 只剩一点血,那么 A 赢;
3. 其他情况 B 赢。
要注意1这种情况就是都只有1滴血这种情况
#include <bits/stdc++.h>

using namespace std;

int main()
{
    int T;
    cin >> T;
    while(T -- )
    {
        int n, k;
        cin >> n >> k;
        if(n == 1)
        {
            cout << "freesin" << endl;
            continue;
        }
        if(n - k <= 1) cout << "pllj" << endl;
        else cout << "freesin" << endl;
    }
    return 0;
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM