• 洛谷 P5664 Emiya 家今天的饭(84分)


    题目传送门

    解题思路:

    对于每一个列c,f[i][j][k]表示到第i行,第c列选了j个,其它列一共选了k个,然后我们读题意发现只要j>k,那就一定是不合法的,然后统计所有方案,减去所有不合法方案,即为答案.

    代码里有注释.

    //只做了84分,懒得写100分(思路一样),以后可能update.....

    84分代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 
     7 long long n,m,a[41][501],sum[41],f[41][41][41],p = 998244353,ans = 1,cd;
     8 
     9 int main() {
    10     scanf("%lld%lld",&n,&m);
    11     for(int i = 1;i <= n; i++) {
    12         for(int j = 1;j <= m; j++){
    13             scanf("%lld",&a[i][j]);
    14             sum[i] += a[i][j] % p;
    15         }
    16         sum[i] %= p;
    17         ans = (ans * (sum[i] + 1) % p) % p;//总方案 
    18     }
    19     for(int c = 1;c <= m; c++) {
    20         memset(f,0,sizeof(f));
    21         f[0][0][0] = 1;
    22         for(int i = 1;i <= n; i++)
    23             for(int j = 0;j <= i; j++)
    24                 for(int k = 0;k <= i - j; k++) {
    25                     f[i][j][k] = f[i-1][j][k] % p;//不选当前行 
    26                     if(j > 0)
    27                         f[i][j][k] += a[i][c] * f[i-1][j-1][k] % p;//选第c列 
    28                     if(k > 0)
    29                         f[i][j][k] += ((sum[i] - a[i][c]) * f[i-1][j][k-1]) % p;//不选第c列 
    30                     f[i][j][k] %= p;
    31                 }
    32         for(int j = 1;j <= n; j++)
    33             for(int k = 0;k <= n - j; k++)
    34                 if(j > k) 
    35                     cd += f[n][j][k];//不合法方案 
    36         cd %= p;
    37     }
    38     printf("%lld",(ans - cd - 1 + p) % p);//-1是因为多加了f[0][0][0]的方案,+p是为了防止负数对答案造成影响. 
    39     return 0;
    40 } 
  • 相关阅读:
    get请求乱码情况
    write()和prinln()的区别?
    校验码实现
    下载图片代码并且解析乱码
    servlet下根据相对路径找资源
    url-pattern配置
    获取网站资源 getResourceAsStream
    Servlet线程安全性
    http1.1 协议响应方面参数
    HTTP1.1协议请求方面参数
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/12025975.html
Copyright © 2020-2023  润新知