贪心|概率|牛客周赛40

文章讲述了在牛客网周赛中,涉及贪心策略和动态规划方法解决关于鸡蛋从高处掉落的问题,讨论了如何通过决策、期望计算以及状态转移来优化解决方案。其中提到的高楼扔鸡蛋问题利用了博弈论思想和二分法技巧,以及处理动态规划中的环和无解情况的方法。
摘要由CSDN通过智能技术生成

子曰:“不得中行而于之,

必也狂乎!狂者进取,

者有所不为也。"

孔子说:”找不到行为合乎中庸的人而和他们交往,一定只能和勇于向前和洁身自好的人交往!勇于向前的人努力进取,洁身自好的人守规矩。

本文讲述牛客周赛40。

图片

结论题,这题的n都是偶数。

我们使用贪心的思想填补。

因为无论n是哪个偶数,可以确定的是,一定有一种方案,使得能用第二种方案完美地填补所有的格子。

图片

分为两个情况,一种情况是n能整除3。

如果n能整除3,毫无疑问,

当然,在这种情况下,如果用第一种格子填补,我们会出现这样的填补方案。

图片

这时候,我们要考虑混搭的情况,也就是使用第一个格子,又使用第二个格子,是否是一个不错的解法。

图片

如果n不整除3的情况下,第二个格子依然能完美地填补,但是第一个格子却不能填补。

图片

图片

图片

图片

图片

图片

先了解条件期望

图片

这道题涉及到决策,并且肯定在第一轮做出决策。

图片

图片

如果不选择我们的期望是容易算出来的。

图片

图片

图片

图片

图片

#include<bits/stdc++.h>using namespace std;double a[200010];double sum[2000010];signed main(){    long long n;    cin>>n;    for(int i=0;i<n;i++)    {        cin>>a[i];    }    sort(a,a+n);    double s=0;    for(int i=0;i<n;i++)        s+=a[i];    if(n<=2)return cout<<s,0;    for(int i=n-1;i>=0;i--)    {        sum[i]=a[i]+sum[i+1];//后缀和    }    double avg=s/n*2;    double res=0;    for(int i=0;i<n;i++)    {        double temp=(s-a[i])/(n-1);        int id=lower_bound(a,a+n,temp)-a;        double E=sum[id]+temp*id;        //减少枚举到a[i]        if(a[i]>=temp)E-=a[i];//如果a[i]比较大,那么我们会多枚举a[i]        else //否则,我们会多枚举temp            E-=temp;        E/=(n-1);        res+=max(avg,E+a[i]);    }    printf("%.7f",res/n);}

有一种类似于和自然博弈的思想,高楼扔鸡蛋。

https://leetcode.cn/problems/super-egg-drop


尽人事听天命-高楼扔鸡蛋|博弈论|动态规划|二分文字

尽人事听天命-高楼扔鸡蛋|博弈论|动态规划|二分法视频

图片

这种做法是超时的,但是为什么我们还需要提这种做法?

因为这种做法是通用的。

#include<bits/stdc++.h>using namespace std;#define double long doubleconst int N=100010;int a[N];int n;double dp[N][3][3];bool st[N][3][3];double dfs(int id,int has,int los){    if(has==2)return 0.l;    if(st[id][has][los])return dp[id][has][los];    st[id][has][los]=true;    for(int i=1;i<=n;i++)    {        if(i==id)continue;                    if(los==0)        {            dp[id][has][los]+=max(dfs(i,has+1,los)+a[i],dfs(id,has,los+1))/(n-has);                   }        else         {            dp[id][has][los]+=(a[i]+dfs(i,has+1,los))/(n-has);        }    }    return dp[id][has][los];}signed main(){    cin>>n;    for(int i=1;i<=n;i++)cin>>a[i];    if(n==1)    {        cout<<a[1];        return 0;    }    if(n==2)    {        cout<<a[1]+a[2];        return 0;    }    double res=dfs(0,0,0);    printf("%.10Lf\n",res);}

这种形式可以用在许多题目上,

图片

图片

#include<bits/stdc++.h>using namespace std;double f[103][103][103];double dp(int a,int b,int c){    if(a>=100||b>=100||c>=100)        return 0;    if(f[a][b][c]>0)return f[a][b][c];    double res=0;    res+=(dp(a+1,b,c)+1)*(double)a/(a+b+c);    res+=(1+dp(a,b+1,c))*(double)b/(a+b+c);    res+=(1+dp(a,b,c+1))*(double)c/(a+b+c);    return f[a][b][c]=res;}signed main(){    int a,b,c;    cin>>a>>b>>c;    printf("%.8f",dp(a,b,c));}

但是,有些时候状态转移会形成一个环,我们有些时候输出无解,有些时候要通过代数变形。
有环的动态规划   

通过代数变形处理的动态规划全期望公式|概率|程序设计|算法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值