洛谷2019 3月月赛 T4

T3做不来。。 直接滚去T4 orz

乍一看 T4是个DP

题干

复杂度??(N^4) 咋优化。。。

还带一只捆绑 捆绑啥的最烦人了

最后20pts 直接废了 T了 很烦

不过拿到80pts已经很开心了惹

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
inline LL read () {
    LL res = 0 ;
    int f (1) ;
    char ch = getchar ();
    while (!isdigit(ch)) {
        if (ch == '-') f = -1 ;
        ch = getchar();
    }
    while (isdigit(ch)) res = (res << 1) + (res << 3) + (ch ^ 48),ch = getchar();
    return res * f ;
}
const int N=1<<7,Mod=1e9+7;
int n;
int f[N*N][N][N];
namespace slove {
    void Init() {
        n=read();
        f[0][1][1] = 1;
        for (register int i = 0; i<n*(n-1); i++)
            for (register int j=1; j<=((i+1>n)?n:i+1); j++)
                for (register int k=j; k<=((i+1>n)?n:i+1); k++)
                    if (f[i][j][k]) {
                        if (i<=k+j-2 and k<n) f[i+1][j][k+1]=(f[i+1][j][k+1]+f[i][j][k])%Mod;
                        else if(((k*(k-1)+j*(j-1))>>1)>=i+1) f[i+1][j][k]=(f[i+1][j][k]+f[i][j][k])%Mod;
                        for (register int l=1; l<=k-j; l++) if (((k*(k-1)+(j+l)*(j+l-1))>>1)>=i+1) f[i+1][j+l][k]=(f[i+1][j+l][k]+f[i][j][k])%Mod;
                    }
    }
    void slove() {
        Init();
        for (register int i=1; i<=n*n-n; i++) {
            LL ans=0;
            for (register int j =1; j<=((i+1>n)?n:i+1); j++)
                for (register int k=j; k<=((i+1>n)?n:i+1); k++) ans=(ans+f[i][j][k])%Mod;
            printf("%d%c",ans," \n"[i==n*n-n]);
        }
    }
}
signed main() {
    return slove::slove(),0;
}

关于100pts ↓

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

template <class T>
inline T Min(const T &a, const T &b) {return a < b ? a : b;}

const int N = 405, M = N * N, ZZQ = 1e9 + 7;

int n, p_limit[N], f[2][N][N], sf[2][N][N], g[2][N], sg[2][N], ans[N * N];

int main()
{
    std::cin >> n;
    for (int i = 1; i <= n; i++)
        p_limit[i] = (n - i + 1) * (n - 1) + (i - 1) * (i - 2) / 2;
    f[1][n][1] = ans[1] = 1;
    for (int i = 1; i <= n; i++) sf[1][i][1] = 1;
    for (int i = 2; i <= Min(n * (n - 1), n << 1); i++)
    {
        int op = i & 1;
        for (int j = 1; j <= n; j++)
            for (int k = 1; k <= n; k++)
                f[op][j][k] = 0;
        for (int j = 1; j <= n; j++) if (i <= p_limit[j])
            for (int k = 1; k <= n; k++) if (i + j >= n + k - 1)
                f[op][j][k] = (f[op ^ 1][j][k] + sf[op ^ 1][j + 1][k - 1]) % ZZQ;
        for (int j = n; j >= 1; j--)
            for (int k = 1; k <= n; k++)
            {
                sf[op][j][k] = (sf[op][j + 1][k] + f[op][j][k]) % ZZQ;
                ans[i] = (ans[i] + f[op][j][k]) % ZZQ;
            }
    }
    for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++)
        g[0][j] = (g[0][j] + f[0][j][k]) % ZZQ;
    for (int j = n; j >= 1; j--) sg[0][j] = (sg[0][j + 1] + g[0][j]) % ZZQ;
    for (int i = (n << 1) + 1; i <= n * (n - 1); i++)
    {
        int op = i & 1;
        for (int j = 1; j <= n; j++) g[op][j] = 0;
        for (int j = 1; j <= n; j++) if (i <= p_limit[j])
            g[op][j] = sg[op ^ 1][j];
        for (int j = n; j >= 1; j--)
        {
            sg[op][j] = (sg[op][j + 1] + g[op][j]) % ZZQ;
            ans[i] = (ans[i] + g[op][j]) % ZZQ;
        }
    }
    for (int i = 1; i <= n * (n - 1); i++) printf("%d ", ans[i]);
    puts("");
    return 0;
}

 

posted @ 2019-03-02 19:46  Isaunoya  阅读(444)  评论(0编辑  收藏  举报
TOP