zoukankan      html  css  js  c++  java
  • 【UOJ Round #1】

    枚举/DP+排列组合


    缩进优化

      QAQ我当时一直在想:$min{ sum_{i=1}^n (lfloorfrac{a[i]}{x} floor + a[i] mod x) }$

      然而并不会做啊……一点思路也没有……主要是后面那个取模非常难受……

      其实正解有点逆向思维的感觉:$ans=sum_{i=1}^n a[i] - max{ sum_{i=1}^n lfloor frac{a[i]}{x} floor *(x-1) } $

      也就是先将a[i]全部加起来,然后再使得被缩掉的部分最大。

      然后……枚举x,枚举x的倍数,数一下除以x为 i 的有多少个就可以了……$O(nlogn)$

     1 //UOJ Round #1 A
     2 #include<vector>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<iostream>
     7 #include<algorithm>
     8 #define rep(i,n) for(int i=0;i<n;++i)
     9 #define F(i,j,n) for(int i=j;i<=n;++i)
    10 #define D(i,j,n) for(int i=j;i>=n;--i)
    11 #define pb push_back
    12 using namespace std;
    13 inline int getint(){
    14     int v=0,sign=1; char ch=getchar();
    15     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    16     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    17     return v*sign;
    18 }
    19 const int N=1e6+10,INF=~0u>>2;
    20 typedef long long LL;
    21 /******************tamplate*********************/
    22 
    23 int a[N],c[N],n;
    24 int main(){
    25 #ifndef ONLINE_JUDGE
    26     freopen("A.in","r",stdin);
    27     freopen("A.out","w",stdout);
    28 #endif
    29     n=getint();
    30     LL sum=0,ans=0;
    31     int mx=0;
    32     F(i,1,n) a[i]=getint(),c[a[i]]++,sum+=a[i],mx=max(mx,a[i]);
    33     D(i,mx,1) c[i]+=c[i+1];
    34     
    35     F(x,1,mx){
    36         LL tmp=0; int i;
    37         for(i=1;(i+1)*x<=mx;i++)
    38             tmp+=(c[i*x]-c[(i+1)*x])*i;
    39         tmp+=c[i*x]*i;
    40         ans=max(ans,tmp*(x-1));
    41     }
    42     printf("%lld
    ",sum-ans);
    43     return 0;
    44 }
    View Code

    外星人

      Orz 题解

      我只想到如果 x<a[i] ,那么a[i]之后放到哪里都不会有影响了……

      对,我们只需要$f[i]$作为状态就够了。用$f[i]$表示$x=i$且只考虑手指数小于等于$i$的外星人的情况下的最优解与方案数。

      怎么转移呢?我们在手指数小于等于$i$的外星人中选一个$a_k$作为下一个发送信息的外星人,显然这个外星人一定是有效外星人。那么考虑手指数介于$(i mod a_k , i]$的外星人,我们发现只要把他们随便插入到$f[i mod a_k]$的最优解排列中去就可以了。这个显然可以用最简单的组合数学解决。方案数即$frac{(N_i -1)!}{N_{i mod a_k}!}$。其中$N_c$表示手指数不超过$c$的外星人个数。

     1 //UOJ Round #1 B
     2 #include<vector>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<iostream>
     7 #include<algorithm>
     8 #define rep(i,n) for(int i=0;i<n;++i)
     9 #define F(i,j,n) for(int i=j;i<=n;++i)
    10 #define D(i,j,n) for(int i=j;i>=n;--i)
    11 #define pb push_back
    12 using namespace std;
    13 inline int getint(){
    14     int v=0,sign=1; char ch=getchar();
    15     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    16     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    17     return v*sign;
    18 }
    19 const int N=5010,INF=~0u>>2,P=998244353;
    20 typedef long long LL;
    21 /******************tamplate*********************/
    22 
    23 int n,m,a[N],c[N],f[N][2],fac[N],inv[N];
    24 int main(){
    25 #ifndef ONLINE_JUDGE
    26     freopen("B.in","r",stdin);
    27     freopen("B.out","w",stdout);
    28 #endif
    29     n=getint(); m=getint();
    30     int mx=m;
    31     F(i,1,n) a[i]=getint(),c[a[i]]++,mx=max(mx,a[i]);
    32     sort(a+1,a+n+1);
    33     F(i,1,mx) c[i]+=c[i-1];
    34 
    35     fac[0]=1;
    36     F(i,1,mx) fac[i]=(LL)fac[i-1]*i%P;
    37     inv[0]=inv[1]=1;
    38     F(i,2,mx) inv[i]=P-(LL)(P/i)*inv[P%i]%P;
    39     F(i,2,mx) inv[i]=(LL)inv[i]*inv[i-1]%P;
    40 
    41     F(i,0,m){
    42         if (c[i]==0) {f[i][0]=i,f[i][1]=1;continue;}
    43         for(int j=1;a[j]<=i && j<=n;j++)
    44             if (f[i%a[j]][0]>f[i][0]){
    45                 f[i][0]=f[i%a[j]][0];
    46                 f[i][1]=(LL)fac[c[i]-1]*inv[c[i%a[j]]]%P*f[i%a[j]][1]%P;
    47             }else if (f[i%a[j]][0]==f[i][0]){
    48                 f[i][1]=(f[i][1]+(LL)fac[c[i]-1]*inv[c[i%a[j]]]%P*f[i%a[j]][1]%P)%P;
    49             }
    50     }
    51     f[m][1]=(LL)f[m][1]*fac[c[mx]]%P*inv[c[m]]%P;
    52     printf("%d
    %d
    ",f[m][0],f[m][1]);
    53     return 0;
    54 }
    View Code
  • 相关阅读:
    在 Flink 算子中使用多线程如何保证不丢数据?
    日处理数据量超10亿:友信金服基于Flink构建实时用户画像系统的实践
    Java编码技巧之高效代码50例
    codeforces 1284D. New Year and Conference(线段树)
    codeforces 1284C. New Year and Permutation(组合数学)
    codeforces 1284B. New Year and Ascent Sequence(二分)
    Codeforces Hello2020 A-E简要题解
    POJ2456 Aggressive cows(二分)
    POJ3122 Pie(二分)
    POJ3258 River Hopscotch(二分最大化最小值)
  • 原文地址:https://www.cnblogs.com/Tunix/p/4589837.html
Copyright © 2011-2022 走看看