7.9模拟赛

T1.gift

有约束的背包。

先把原序列排序,从小到大,对于其中第x个元素,我们假设它是最小的没有被选的物品,那么小于a[x]的都要被强制选择。

这就会影响统计答案的区间,变成( m-s[i-1],m-s[i] ]。

其余正常转移即可。

#include<algorithm>
#include<iostream>
#include<cstdio>

using namespace std;

const int MAXN=1005;
const int MOD=1e9+7;


int f[MAXN];
int a[MAXN],s[MAXN];

int n,m,ans;

int main(){
    cin>>n>>m;
    f[0]=1;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
    for(int i=n;i>=1;i--){
        for(int j=m-s[i-1];j>=0&&j>m-s[i];j--)(ans+=f[j])%=MOD;
        for(int j=m;j>=a[i];j--)(f[j]+=f[j-a[i]])%=MOD;
    }
    if(s[n]<=m) ans++;
    cout<<ans%MOD;
    return 0;
}

 T2.fseq

求概率,想到分母肯定是C(n+m,n),可是分子呢。。

把+1看成向右走,-1看成向上走,就是在一个N*M的网格图中从原点走到(N,M)的方案数了,这是一个不降路径问题 ,答案为C(n+m,n)

可是这里说任意前缀和不能小于0,所以我们可以形象化这个约束条件,也就是不穿过对角线,神奇的卡特兰数来了。

(C(n+m,n)-C(n+m,n-1))/C(n+m,n)

化简以后就是1-m/(n+1)

代码实现,注意m>n的情况要特判。

猜你喜欢

转载自www.cnblogs.com/ghostcai/p/9285781.html