• UOJ #22 UR #1 外星人


    LINK:#22. UR #1 外星人

    给出n个正整数数 一个初值x x要逐个对这些数字取模 问怎样排列使得最终结果最大 使结果最大的方案数又多少种?

    n<=1000,x<=5000.

    考虑一个排列真正的有效取模只有当 (xgeq a_i)时才行 所以x通过一个排列真正有效的数字必然是从大到小排列的。

    求第一问 不难想到将模数从大到小排列 设f[i][j]表示到达第i个模数此时值为j是否可行。

    这样dp下来我们只需要取出小于minn的那个可行值最大的即可。

    考虑方案数 这样dp同样有效。

    不过复杂度 (n^2cdot x) 比较高。

    考虑优化 不难发现对于f[i][j]来说 如果 j比(a_{i-1})还要小 那么没有必要再把状态传到i-1了 直接让i-1在后面位置中随便选择一个位置即可。

    设状态f[i]表示权值到达i的方案数.

    此时只有<=i的模数才能优影响 且前面的所有模数已经被我们安排好位置了。

    如果选择了一个模数 (a_j) 那么 设w=i%(a_j) 权值在i-1到w+1之间的模数便没用了随便排个位置即可。

    复杂度(nx) 可以通过.(值得一提的是 最后能获得的最大值尽量用标记来判断 因为方案数要取模,(刚好模为0 就脸黑了.

    const int MAXN=5010;
    int n,m,minn;
    int a[MAXN],vis[MAXN],b[MAXN];
    ll f[MAXN],inv[MAXN],fac[MAXN];
    inline ll ksm(ll b,int p){ll cnt=1;while(p){if(p&1)cnt=cnt*b%mod;b=b*b%mod;p=p>>1;}return cnt;}
    inline void prepare()
    {
    	fac[0]=1;
    	rep(1,n,i)fac[i]=fac[i-1]*i%mod;
    	inv[n]=ksm(fac[n],mod-2);
    	fep(n-1,0,i)inv[i]=inv[i+1]*(i+1)%mod;
    }
    int main()
    {
    	freopen("1.in","r",stdin);
    	get(n);get(m);minn=INF;
    	rep(1,n,i)get(a[i]),minn=min(minn,a[i]),++vis[a[i]];
    	rep(1,m,i)vis[i]+=vis[i-1];
    	prepare();f[m]=fac[n]*inv[vis[m]]%mod;
    	sort(a+1,a+1+n);
    	fep(m,1,i)
    	{
    		if(!f[i])continue;
    		rep(1,n,j)
    		{
    			if(a[j]>i)break;
    			f[i%a[j]]=(f[i%a[j]]+f[i]*fac[vis[i]-1]%mod*inv[vis[i%a[j]]])%mod;
    		}
    	}
    	fep(minn-1,0,i)if(f[i]){printf("%d %lld
    ",i,f[i]);return 0;}
    }
    
  • 相关阅读:
    [js开源组件开发]ajax分页组件
    使用nodejs+express+socketio+mysql搭建聊天室
    [js开源组件开发]图片放大镜
    JY游戏之毁经典《扫雷》
    JY游戏之手游《打卡乐猫》
    [js开源组件开发]图片懒加载lazyload
    [js开源组件开发]js文本框计数组件
    [js开源组件开发]js轮播图片支持手机滑动切换
    [js开源组件开发]js手机联动选择日期 开源git
    [js开源组件开发]-手机端照片预览组件
  • 原文地址:https://www.cnblogs.com/chdy/p/12599956.html
Copyright © 2020-2023  润新知