reward

题目大意

球的个数在0..M中,将球分到N个盒子里,每个盒子可以没有,问方案数,答案模P。
N,M,P<=10^9,将P分成互不互质的数的乘积,且这些数均可表示为质数的幂,最大的数<=10^5。

隔板问题

我们可以看作将M个球放入N+1个盒子里,由于每个盒子可以没有,所以方案数为CNN+M
考虑该如何进行组合数取模呢?

中国剩余定理

将P分解成互不互质的数的乘积,且这些数均可表示为质数的幂。那么我们可以列出模方程,于是可以利用中国剩余定理解出模P剩余系下的唯一解,即为组合数模P的值。于是,我们现在需要做的,是如何快速算组合数模一个质数的幂。

快速算阶乘

设p为要模的数,pp为p唯一的质因子。
我们可以统计最终结果有多少个pp,计为cnt。然后计算分子除pp外的积为A,分母除pp外的积为B,答案即为AB1ppcnt模p的值。
现在我们考虑如何快速统计阶乘中有多少个pp以及阶乘除pp外的积。
举个例子,p=9,pp=3,n=20
1234567891011121314151617181920
我们发现,每9个为一个周期,即
124578Mod9=101113141617Mod9=192022232526Mod9
我们预处理fac[i]表示i中排除pp的倍数的积,可知一个周期值为fac[p-1]。
对于上面那个例子等价于
(124578)23691215181920
余下部分为fac[n%p]。
然后只剩下
369121518
因此cnt+=n/pp。剩余部分可以变为
123456
继续递归处理即可。附代码理解:

ll calcfac(ll n,ll p,ll pp){
    if (n<pp) return fac[n];
    ll t=quicksortmi(fac[p-1],n/p,p);
    t=t*fac[n%p]%p;
    cnt+=n/pp;
    t=t*calcfac(n/pp,p,pp)%p;
    return t;
}

因此本题解决。

参考程序

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
ll a[20],b[20],c[20],d[20],e[20],pri[32000+10],fac[100000+10],num[100000+10];
bool bz[32000+10];
ll i,j,k,l,t,n,m,p,pp,top,xx,yy,ans,cnt;
ll quicksortmi(ll x,ll y,ll p){
    if (!y) return 1;
    if (y==1) return x%p;
    ll t=quicksortmi(x,y/2,p);
    t=t*t%p;
    if (y%2) t=t*(x%p)%p;
    return t;
}
void gcd(ll a,ll b){
    if (!b){
        xx=1;
        yy=0;
    }
    else{
        gcd(b,a%b);
        swap(xx,yy);
        yy-=xx*(a/b);
    }
}
ll getny(ll x,ll y){
    gcd(x,y);
    xx=(xx%y+y)%y;
    return xx;
}
ll calcfac(ll n,ll p,ll pp){
    if (n<pp) return fac[n];
    ll t=quicksortmi(fac[p-1],n/p,p);
    t=t*fac[n%p]%p;
    cnt+=n/pp;
    t=t*calcfac(n/pp,p,pp)%p;
    return t;
}
ll calc(ll x,ll y,ll p,ll pp){
    ll i,j;
    fac[0]=1;num[0]=0;
    fo(i,1,p-1){
        num[i]=0;
        j=i;
        while (j%pp==0){
            num[i]++;
            j/=pp;
        }
        num[i]+=num[i-1];
        if (i%pp==0) fac[i]=fac[i-1];
        else fac[i]=fac[i-1]*i%p;
    }
    cnt=0;
    ll A=calcfac(y,p,pp);
    ll tot=cnt;
    cnt=0;
    ll B=calcfac(x,p,pp);
    B=B*calcfac(y-x,p,pp)%p;
    B=getny(B,p);
    return A*B%p*quicksortmi(pp,tot-cnt,p)%p;
}
int main(){
    //freopen("E:/wzd/11.28/yj.txt","w",stdout);
    scanf("%lld%lld%lld",&n,&m,&p);
    fo(i,2,32000){
        if (!bz[i]) pri[++k]=i;
        fo(j,1,k){
            if (pri[j]*i>32000) break;
            bz[i*pri[j]]=1;
            if (i%pri[j]==0) break;
        }
    }
    pp=p;
    fo(i,1,k){
        if (pp%pri[i]==0){
            d[++top]=1;e[top]=pri[i];
            while (pp%pri[i]==0){
                d[top]*=pri[i];
                pp/=pri[i];
            }
        }
    }
    if (pp>1){
        d[++top]=pp;
        e[top]=d[top];
    }
    fo(i,1,top) c[i]=p/d[i];
    fo(i,1,top) a[i]=calc(n,n+m,d[i],e[i]);
    fo(i,1,top) b[i]=getny(c[i],d[i]);
    fo(i,1,top) ans=(ans+a[i]*b[i]%p*c[i]%p)%p;
    printf("%lld\n",ans);
    return 0;
} 
Reward收敛在强化学习中是一个重要概念,与型评估紧密相关,它涉及到型训练过程中奖励信号的稳定性和有效性。 ### 定义 Reward收敛指的是在强化学习训练过程中,智能体所获得的奖励随着训练的进行逐渐趋于稳定,达到一个相对固定的值或在一个较小的范围内波动。这意味着智能体的策略在不断优化,能够持续获得较为稳定的奖励,反映了型的收敛性,是评估型性能的一个重要指标 [^2]。 ### 收敛的重要性 Reward收敛对于评估型具有多方面的意义。它可以用于评估型的收敛性,判断型是否能够在训练过程中逐渐找到最优策略;评估型的泛化能力,即型在不同环境或任务中的适应能力;还能评估型的鲁棒性,也就是型在面对噪声或干扰时的稳定性 [^2]。 ### 影响收敛的原因 - **奖励函数设计**:传统的奖励函数设计方法依赖人工设计,耗时且难以保证效果。如果奖励信号过于稀疏,智能体可能难以学习到有效的策略,导致收敛困难;奖励函数存在偏差,会使智能体学习到错误的行为,影响收敛效果 [^1][^4]。 - **人类反馈质量和数量**:在一些基于人类反馈的强化学习方法中,如RLHF,高质量的偏好数据可以显著提高型的收敛速度,而低质量或数量不足的反馈会导致收敛速度变慢 [^4]。 - **奖励黑客问题**:型可能学会利用奖励函数的漏洞来获取高奖励,而不是真正学习人类偏好的行为,这会干扰型的正常学习过程,影响收敛 [^4]。 ### 解决方法 - **Reward Modeling方法**:通过学习型预测人类的奖励偏好,为智能体提供更准确的奖励信号,从而降低奖励函数设计难度,提高策略质量,有助于奖励收敛 [^1]。 - **优化方法**:如RLHF - V提出的DDPO,直接优化型对细粒度人类偏好的学习,提高型对奖励的学习效果,促进收敛 [^4]。 - **利用人类反馈优化奖励函数**:像TEXT2REWARD框架,通过在环境中执行学习到的策略,获取人类反馈,并相应地优化奖励函数,解决强化学习训练的敏感性和语言的歧义性问题,使奖励趋于稳定 [^3]。 ### 代码示例 以下是一个简单的Q - learning算法示例,用于说明强化学习中奖励的更新过程: ```python import numpy as np # 定义环境参数 num_states = 5 num_actions = 2 gamma = 0.9 # 折扣因子 alpha = 0.1 # 学习率 # 初始化Q表 Q = np.zeros((num_states, num_actions)) # 拟训练过程 num_episodes = 100 rewards_per_episode = [] for episode in range(num_episodes): state = 0 total_reward = 0 done = False while not done: # 选择动作 action = np.argmax(Q[state, :]) # 拟环境反馈 next_state = (state + 1) % num_states reward = 1 if next_state == 3 else 0 # 更新Q表 Q[state, action] = (1 - alpha) * Q[state, action] + alpha * (reward + gamma * np.max(Q[next_state, :])) state = next_state total_reward += reward if state == 4: done = True rewards_per_episode.append(total_reward) # 打印每一轮的总奖励 print(rewards_per_episode) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值