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
  • 相关阅读:
    用webservice实现的一个天气预报程序
    让VS.net2005手机模拟器上网
    EVC4.0 PPC2003 Emulator 转中文版
    BSTR转CString
    在pocket pc 2003上播放声音
    VC++.net 2005 SmartDevice 屏幕转向
    c#.net2005 调用evc4.0生成的dll文件
    Json
    adb 命令模拟按键事件
    bat 截取字符
  • 原文地址:https://www.cnblogs.com/Peter0701/p/11742020.html
Copyright © 2011-2022 走看看