• Atcoder arc096


    C:Half and Half

    几个if语句贪心算一算就好了

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 int a,b,c,x,y,t;
     5 int main()
     6 {
     7     scanf_s("%d%d%d%d%d",&a,&b,&c,&x,&y);c*=2;
     8     a=min(a,c);b=min(b,c);
     9     if (a+b<=c) printf("%d
    ",x*a+y*b);
    10     else t=min(x,y),printf("%d
    ",t*c+(x-t)*a+(y-t)*b);
    11     return 0;
    12 } 

    D:Static Sushi

    这是个环形吧台,所以可以正着走、倒着走、正着走再倒着走、倒着走再正着走。

    记录一个前缀和即可。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long ll;
     5 const int N=100005;
     6 int n,pos1,pos2; 
     7 ll C,x[N],w[N],sum,Max,Max1[N],Max2[N];
     8 int main()
     9 {
    10     scanf("%d%lld",&n,&C);
    11     for (int i=1;i<=n;i++) scanf("%lld%lld",&x[i],&w[i]);
    12     for (int i=1;i<=n;i++) 
    13       sum+=w[i],Max1[i]=max(Max1[i-1],sum-x[i]);
    14     sum=0;
    15     for (int i=n;i>=1;i--) 
    16        sum+=w[i],Max2[i]=max(Max2[i+1],sum-(C-x[i]));
    17     Max=max(Max1[n],Max2[1]);
    18     sum=0;
    19     for (int i=1;i<=n;i++) sum+=w[i],Max=max(Max,Max2[i+1]+sum-x[i]*2); 
    20     sum=0;
    21     for (int i=n;i>=1;i--) sum+=w[i],Max=max(Max,Max1[i-1]+sum-(C-x[i])*2);
    22     printf("%lld
    ",Max);
    23     return 0;
    24 }

    晚了五分钟开,名次掉飞真是不开心。。。

    E:Everything on it

    可以选择任意碗拉面,每碗的配料组合必须不同。配料一共有$n$种,$2^n$种组合。问有多少种选拉面的方案可以使得每一种配料都至少出现了两次?$n<=3000$。

    容斥。设f[i]为至少有i种配料出现次数<=1的方案数。那么$ans=sum_{i=0}^{n}((-1)^i*f[i]*C(n,i))$。

    怎么求f[i]?比较麻烦的地方是一个数中有多个配料,怎么来保证选取的i个配料必然出现<=1次?

    考虑第二类斯特灵数的前缀和s[i][j]表示<=i个元素分到非空的j的集合的方案数。

    即i种配料要么不出现,要么被分到集合中,同一个集合的出现在同一个二进制数里,有$2^ {n-i}$种方案(其他n-i种随意,这一个集合中的同时出现)。有j个集合,不同集合之间独立,就有$(2^{n-i})^j$种方案。其余n-i种配料的组合任意,因此$f[i]=sum_{j=0}^{i}s[i][j]*2^{(n-i)*j}*2^{2^{n-i}}$。

     1 #include<cstdio>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=3005;
     5 int ans,n,mod,jc[N],inv[N],s[N][N],f[N],pw[N*N];
     6 int ksm(int x,int y,int mod)
     7 {
     8   int res=1;
     9   while (y) {if (y&1) res=(ll)res*x%mod;x=(ll)x*x%mod;y>>=1;}
    10   return res;
    11 }
    12 int c(int n,int m) {return (ll)jc[n]*inv[m]%mod*inv[n-m]%mod;}
    13 int main()
    14 {
    15     scanf("%d%d",&n,&mod);
    16     jc[0]=jc[1]=inv[0]=inv[1]=pw[0]=1;
    17     for (int i=2;i<=n;i++) jc[i]=(ll)jc[i-1]*i%mod,inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
    18     for (int i=2;i<=n;i++) inv[i]=(ll)inv[i-1]*inv[i]%mod;
    19     for (int i=1;i<=n*n;i++) pw[i]=(ll)pw[i-1]*2%mod;
    20     for (int i=0;i<=n;i++) s[i][0]=1;//初始化,都有一种可能分到0个集合 
    21     for (int i=1;i<=n;i++)
    22       for (int j=1;j<=i;j++)
    23         s[i][j]=((ll)s[i-1][j-1]+(ll)(j+1)*s[i-1][j]%mod)%mod;//<=i个元素分入j个非空集合的方案数  
    24     for (int i=0;i<=n;i++)
    25     {
    26        for (int j=0;j<=i;j++) f[i]=((ll)f[i]+(ll)s[i][j]*pw[(n-i)*j]%mod)%mod;
    27        f[i]=(ll)f[i]*ksm(2,ksm(2,n-i,mod-1),mod)%mod;    
    28     }
    29     for (int i=0;i<=n;i++)
    30       if (i&1) ans=((ll)ans-(ll)c(n,i)*f[i]%mod+mod)%mod;
    31       else ans=((ll)ans+(ll)c(n,i)*f[i]%mod)%mod;
    32     printf("%d
    ",ans);
    33     return 0;
    34 }

    F:不会,待填坑

  • 相关阅读:
    让DateTimePicker显示空时间值 (转) 武胜
    Webcam in C#: AForge.NET (转) 武胜
    C#自定义事件的步骤 武胜
    交换机VLAN的配置 (转) 武胜
    虚拟LAN安全的最佳实践经验 (转) 武胜
    绿色版 MySQL 的安装配置 (转) 武胜
    net 中捕获摄像头视频的方式及对比(How to Capture Camera Video via .Net) (转) 武胜
    C# WndProc的使用方法 (转) 武胜
    金融证券业Windows NT服务器热备份系统工作示意图 (转) 武胜
    ubuntu下配置samba实现文件夹共享
  • 原文地址:https://www.cnblogs.com/Scx117/p/8906140.html
Copyright © 2020-2023  润新知