UOJ 外星人

Posted rhythm-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ 外星人相关的知识,希望对你有一定的参考价值。

题目:

2044年,Picks建成了人类第一台基于量子理论的银河系信息传递机。Picks游遍了宇宙,雇用了n个外星人来帮他作为信息传递机的中转站。我们将外星人依次编号为1 到n,其中i 号外星人有ai 根手指。外星人都是很低级的,于是Picks花费了很大的精力,才教会他们学会扳手指数数。Picks现在准备传递x 个脉冲信号给VFleaKing,于是他把信号发给1号外星人,然后1号外星人把信号发送给2号外星人,2号外星人把信号发送给3号外星人,依次类推,最后n号外星人把信号发给VFleaKing。但是事情没有Picks想象的那么顺利,由于外星人手指个数有限,所以如果i 号外星人收到了t 个脉冲信号,他会错误的以为发送过来的是tmodai 个脉冲信号,导致只发送了tmodai个脉冲信号出去。Picks希望他发送出去的脉冲信号数量x 与VFleaKing收到的脉冲信号数量y 的差的绝对值尽量小。于是他决定通过重新排列这些外星人的顺序来达到这一目的。请你求出与x 之差最小的y。除此之外,请求出有多少种排列外星人的方式能达到最优解,你只需要输出方案数对998244353(7×17×223+1,一个质数)取模后的结果。

分析:

先把元素从大到小排序,对于新出现的最小值点ai就是关键点。设dp[i][j]为对前i个数取模后余数为j的方案数。当ai为关键点时状态转移方程为:dp[i][j%a[i]]+=dp[i-1][j],当ai为非关键点时状态转移方程为dp[i][j]+=(n-1)*dp[i-1][j]

技术分享图片
#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#define range(i,a,b) for(int i=a;i<=b;++i)
#define LL long long
#define rerange(i,a,b) for(int i=a;i>=b;--i)
#define fill(arr,tmp) memset(arr,tmp,sizeof(arr))
using namespace std;
int n,d,a[1005],dp[1005][5005];
const int DEV=998244353;
bool cmp(int a,int b){
    return a>b;
}
void init(){
    cin>>n>>d;
    range(i,1,n)cin>>a[i];
    sort(a+1,a+1+n,cmp);
    dp[0][d]=1;
}
void solve(){
    range(i,1,n){
        range(j,0,d)dp[i][j]=((LL)dp[i][j]+(LL)dp[i-1][j]*(n-i)%DEV)%DEV;
        range(j,0,d)dp[i][j%a[i]]=((LL)dp[i][j%a[i]]+dp[i-1][j])%DEV;
    }
    rerange(i,a[n]-1,0)if(dp[n][i]){
        cout<<i<<endl<<dp[n][i]<<endl;
        break;
    }
}
int main() {
    init();
    solve();
    return 0;
}
View Code

 

以上是关于UOJ 外星人的主要内容,如果未能解决你的问题,请参考以下文章

UOJ#22UR#1外星人

[UOJ22]外星人

uoj22 外星人

跪求2011年终回顾166部电影大混剪里面的音乐名及各部电影名称

外星人代码出现在wordpress安装关键文件中

Python从入门到实践里的《外星人入侵》 ,记分部分代码错误,帮忙解答一下?