zoukankan      html  css  js  c++  java
  • $Luogu$ $P2911$ $[USACO08OCT]$ 牛骨头 $Bovine$ $Bones$

    链接

    背景

    (USACO) (2008) (Oct) (Gold) (T1)(Luogu) (P2911/BZOJ1599)

    题意

    给定三个骰子,分别有 (s1,s2,s3) 个面(每个骰子从 (1) 开始标号每个面)。求出现次数最多的三骰子数字和。有多个数字和出现次数均为最多时,只要求最小的数字和。

    解法

    从朴素解法开始:由于 (s1 leqslant 20,s2 leqslant 20,s3 leqslant 40) ,故不难想到 (O(s1s2s3)) 枚举出所有的情况,开个桶记下所有三骰子数字和的出现次数,找出最大的桶所在的位置即可。

    另一种解法

    是否有一个数学方法可以 (O(1)) 计算答案呢?显然是有的。
    不妨绘出出现次数的分布图像(如下图),

    发现最值点在相当长的一段区间内分布。假设 (s1 leqslant s2 leqslant s3) ,则通过观察或打表容易发现在 (s1+s2<s3) 时,最值点区间的左端点(即本题答案)为 (s1+s2+1) ;否则答案为 (frac{s1+s2+s3+3}{2}) (根据每个点数的期望计算)。

    代码

    $View$ $Code$ ```cpp #include using namespace std; inline int read() { int ret=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { ret=(ret<<1)+(ret<<3)+ch-'0'; ch=getchar(); } return ret*f; } int s1,s2,s3,cnt[85],ans,maxn; int main() { s1=read(); s2=read(); s3=read(); for(register int i=1;i<=s1;i++) for(register int j=1;j<=s2;j++) for(register int k=1;k<=s3;k++) cnt[i+j+k]++; for(register int i=1;i<=s1+s2+s3;i++) { if(maxn

    另一份代码

    $View$ $Code$ ```cpp #include using namespace std; inline int read() { int ret=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { ret=(ret<<1)+(ret<<3)+ch-'0'; ch=getchar(); } return ret*f; } int s1,s2,s3,cnt[85],ans,maxn; int main() { s1=read(); s2=read(); s3=read(); if(s1+s2
  • 相关阅读:
    python 函数
    python升级功能
    python3与c++的不同点(初学看重点~)
    python中的数据结构
    github超简单用法
    ListView
    线性代数(1)--方程组的同解变形
    C++基础学习
    C++多态
    PKU《程序设计》专项课程_递归汉诺塔问题
  • 原文地址:https://www.cnblogs.com/Peter0701/p/11742020.html
Copyright © 2011-2022 走看看