zoukankan      html  css  js  c++  java
  • uoj22 【UR #1】外星人

    link

    题意:

    给一个长为n的序列a[],现在有一个初始值m,问一个1~n的排列p[],满足将m对a[p[i]]顺次取模后得到的值最大,输出最大值和方案数。

    $n,mleq 5 imes 10^3.$

    题解:

    如果存在i,j满足i<j&&a[i]<a[j],那么这个a[j]是没有用的,取不取模效果一样。

    考虑将a[]从大到小排序,原问题转化为从左往右选择若干个数取模,所得的最大值以及方案数。定义f[i][j]表示操作到前i个数%之后值为j的方案数。

    考虑转移,我们从小到大加数:

    如果当前数取模,那么这个数的位置唯一(放在n-i个数之前);否则这个数可以放在n-i个数的任意一个空之间,n-i种方案。

    复杂度$mathcal{O}(n imes m).$

    code:

     1 #include<bits/stdc++.h>
     2 #define rep(i,x,y) for (int i=(x);i<=(y);i++)
     3 #define per(i,x,y) for (int i=(x);i>=(y);i--)
     4 #define ll long long
     5 #define inf 1000000001
     6 #define y1 y1___
     7 using namespace std;
     8 char gc(){
     9     static char buf[100000],*p1=buf,*p2=buf;
    10     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    11 }
    12 #define gc getchar
    13 ll read(){
    14     char ch=gc();ll x=0;int op=1;
    15     for (;!isdigit(ch);ch=gc()) if (ch=='-') op=-1;
    16     for (;isdigit(ch);ch=gc()) x=(x<<1)+(x<<3)+ch-'0';
    17     return x*op;
    18 }
    19 #define N 5005
    20 #define mod 998244353
    21 int n,m,a[N],f[N][N];
    22 void upd(int &x,int y){x+=y;x-=x>=mod?mod:0;}
    23 int main(){
    24     n=read(),m=read();
    25     rep (i,1,n) a[i]=read();
    26     sort(&a[1],&a[n+1],greater<int>());
    27     f[0][m]=1;
    28     rep (i,1,n) rep (j,0,m) if (f[i-1][j]){
    29         upd(f[i][j],(ll)(n-i)*f[i-1][j]%mod);
    30         upd(f[i][j%a[i]],f[i-1][j]);
    31     }
    32     per (i,a[n]-1,0) if (f[n][i]) return printf("%d
    %d
    ",i,f[n][i]),0;
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    基础抽象代数
    斜堆
    WC2018
    WC2019
    有向图上不相交路径计数
    生成树计数
    Pr&#252;fer序列
    反演
    1.1 Linux中的进程 --fork、孤儿进程、僵尸进程、文件共享分析
    Python程序的执行过程 解释型语言和编译型语言
  • 原文地址:https://www.cnblogs.com/bestFy/p/9369078.html
Copyright © 2011-2022 走看看