zoukankan      html  css  js  c++  java
  • 20200720T1【CQOI2008】矩阵的个数(洛谷 P5784)

    Description

    给出一个N行3列非负整数矩阵的各行各列之和,统计有多少个矩阵满足此条件。输出答案模10^17的值。

    Input

    第一行包含四个正整数N,c1, c2, c3,即行数与三列之和。第二行包含N个正整数,即各行三个数之和。每行每列之和均不超过125。

    Output

    仅一个数,满足条件的矩阵个数模10^17的值。

    Sample Input

    3 2 3 4
    1 2 6

    Sample Output

    17

    Hint

     1<=N<=200

     Solution

    T1一看就没思路,丢给zjy1412打了手暴力dfs

     1 void dfs(int x,int l1,int l2,int l3){
     2     if(x==n){
     3         ans++;
     4         if(ans>=P)ans-=P;//其实没必要了,等你运行到1e17.........
     5         return;
     6     }
     7     for(int i=(l1<d[x]?l1:d[x]);i>=0;i--){
     8         if(l2+l3<d[x]-i)break;
     9         for(int j=(l2<d[x]-i?l2:d[x]-i);j>=0;j--){
    10             if(l3<d[x]-i-j)break;
    11             dfs(x+1,l1-i,l2-j,l3-(d[x]-i-j));
    12         }
    13     }
    14 }
    //dfs(1,c1,c2,c3);

    答案都要模1e17,显然T飞

    起码还有30points

    正解是DP

    f[i][j][k]表示前i行第一列和为j,第二列和为k的方案数

    一行就三个数,知道两个另外一个也就知道了

    f[i][j][k]=∑ f[i-1][j-x][k-y]

    f[0][0][0]=1

    x和y表示这一行第一列放x,第二列放y

    发现i只与i-1有关,所以可以滚掉一维

    判断一下j,k,c3+j+k,x,y的条件即可

    code

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<queue>
     7 #include<vector>
     8 #include<stack>
     9 #include<set>
    10 #include<deque>
    11 #include<map>
    12 using namespace std;
    13 
    14 template <typename T> void read(T &x) {
    15     x = 0; int f = 1; char c;
    16     for (c = getchar(); c < '0' || c > '9'; c = getchar()) if (c == '-') f = -f;
    17     for (; c >= '0' && c <= '9'; c = getchar()) x = 10 * x + c - '0' ;
    18     x *= f;
    19 }
    20 template <typename T> void write(T x){
    21     if (x < 0) putchar('-'), x = -x;
    22     if (x > 9) write(x / 10);
    23     putchar(x % 10 + '0');
    24 }
    25 template <typename T> void writeln(T x) { write(x); putchar('
    '); }
    26 template <typename T> void writesn(T x) { write(x); putchar(' '); }
    27 
    28 #define int long long
    29 #define inf 1234567890
    30 #define next net
    31 #define P 100000000000000000
    32 #define N 205
    33 #define mid ((l+r)>>1)
    34 #define lson (o<<1)
    35 #define rson (o<<1|1)
    36 #define R register
    37 
    38 int n,c1,c2,c3,d[N],top[N],ans;
    39 int f[N][N][2];
    40 signed main(){
    41     read(n);read(c1);read(c2);read(c3);
    42     for(R int i=1;i<=n;i++)read(top[i]),d[i]=d[i-1]+top[i];
    43     f[0][0][0]=1;
    44     for(R int i=1;i<=n;i++){  //先枚举所有状态j,k
    45         for(R int j=0;j<=c1 && j<=d[i];j++){
    46             for(R int k=0;k<=c2 && j+k<=d[i];k++){//注意j,k是这一列的和
    47                 f[j][k][(i&1)]=0;
    48                 if(c3+j+k<d[i])continue;  //再枚举转移x,y
    49                 for(R int x=0;x<=j && x<=top[i];x++){//x,y才是这一行填的数
    50                     for(R int y=0;y<=k && x+y<=top[i];y++){
    51                         f[j][k][(i&1)]+=f[j-x][k-y][(i&1)^1];
    52                         f[j][k][(i&1)]%=P;
    53                     }
    54                 }
    55             }
    56         }
    57     }
    58     writeln(f[c1][c2][n&1]);
    59     return 0;
    60 }
  • 相关阅读:
    《鱼嘤嘤小分队》第一次作业:项目选题
    第一次博客作业
    csp 201709-2 优先队列模拟
    csp 201403-2
    csp 201809-2 买菜
    JavaScript中伪协议
    修改placeholder的样式
    jQuery对象与DOM对象之间的转换方法
    a的样式
    Guid.NewGuid() 和 new Guid()的区别
  • 原文地址:https://www.cnblogs.com/e-e-thinker/p/13345327.html
Copyright © 2011-2022 走看看