• 比赛-训练赛 (15 Aug, 2018)


    1.) 2357数

    单调队列或者搜索都行。

    #include <cstdio>
    #include <deque>
    
    using namespace std;
    
    typedef long long ll;
    
    deque<ll> A[4];
    
    int main()
    {
    	ll N, x;
    	scanf("%lld", &N);
    	x = 1;
    	while (x < N) {
    		A[0].push_back(x * 2);
    		A[1].push_back(x * 3);
    		A[2].push_back(x * 5);
    		A[3].push_back(x * 7);
    		int p = 0;
    		for (int i = 1; i <= 3; ++i) {
    			if (A[i].front() < A[p].front())
    				p = i;
    		}
    		x = A[p].front();
    		for (int i = 0; i <= 3; ++i) {
    			if (A[i].front() == A[p].front())
    				A[i].pop_front();
    		}
    	}
    	printf("%lld
    ", x);
    	return 0;
    }
    

    2.) 监狱

    区间 DP 。枚举区间内第一个被释放的人来转移状态。

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    const int INF = 1e9;
    const int _N = 200;
    
    int A[_N], B[15], f[_N][_N], N, M, ans;
    bool mk[_N];
    
    void test()
    {
    	int cnt = 0;
    	for (int i = 1; i <= N; ++i)
    		mk[i] = 0;
    	for (int i = 1; i <= M; ++i) {
    		int j;
    		mk[A[B[i]]] = 1;
    		for (j = A[B[i]] - 1; j >= 1 && !mk[j]; --j);
    		cnt += A[B[i]] - 1 - j;
    		for (j = A[B[i]] + 1; j <= N && !mk[j]; ++j);
    		cnt += j - 1 - A[B[i]];
    	}
    	ans = min(ans, cnt);
    	return;
    }
    
    void fun1()
    {
    	for (int i = 1; i <= M; ++i)
    		B[i] = i;
    	ans = INF;
    	test();
    	while (next_permutation(B + 1, B + 1 + M))
    		test();
    	printf("%d
    ", ans);
    	return;
    }
    
    int dfs(int l, int r)
    {
    	if (f[l][r] != -1) {
    		return f[l][r];
    	}
    	if (l == r) {
    		return f[l][r] = 0;
    	}
    	f[l][r] = INF;
    	for (int i = l; i <= r; ++i) {
    		f[l][r] = min(f[l][r], dfs(l, i) + dfs(i + 1, r) + A[r] - A[l - 1] - 2);
    	}
    //	printf("[%d, %d] = %d
    ", l, r, f[l][r]);
    	return f[l][r];
    }
    
    int main()
    {
    	
    	scanf("%d%d", &N, &M);
    	for (int i = 1; i <= M; ++i) {
    		scanf("%d", &A[i]);
    	}
    	if (N <= 105 && M <= 6) {
    		fun1();//O(M! * N * M)
    		return 0;
    	}
    	sort(A + 1, A + 1 + M);
    	A[0] = 0, A[M + 1] = N + 1;
    	memset(f, -1, sizeof f);
    	printf("%d
    ", dfs(1, M + 1));
    	return 0;
    }
    

    3.) lucknum

    数位 DP 可以拿到 60 分。注意到 DP 方程和组合数的递推式很像。考虑把 (n) 个数位作为球,把这些球扔到 (m) 表示 ([0, m-1])(m) 个数字的桶里去(或分成 (m) 份)。扔完后按桶表示的数字大小从小到大排序,把扔到桶内的球对应的数位上的数,设置为桶表示的数字,就得到了一个合理的 lucknum 。桶内可以为空。隔板法搞一下答案就是 (left(_{m-1}^{n+m-1} ight))

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    typedef long long ll;
    
    ll N, M, P;
    
    ll mont(ll t1, ll t2)
    {
    	t1 %= P;
    	ll t = 1;
    	while (t2) {
    		if (t2 & 1)
    			t = t * t1 % P;
    		t2 >>= 1;
    		t1 = t1 * t1 % P;
    	}
    	return t;
    }
    
    int main()
    {
    	ll dn, up;
    	scanf("%lld%lld%lld", &N, &M, &P);
    	dn = M + N - 1;
    	up = M - 1;
    	if (up > dn - up)
    		up = dn - up;
    	ll t0 = 1, t1 = 1;
    	for (ll i = 1; i <= up; ++i) {
    		t0 = t0 * i % P;
    		t1 = t1 * (dn - i + 1) % P;
    	}
    	printf("%lld
    ", t1 * mont(t0, P - 2) % P);
    	return 0;
    }
    
  • 相关阅读:
    接口测试
    Appium应用
    adb常用指令与APPium环境搭建
    移动端专项测试
    tomcat修改端口号
    Linux之Redis安装
    FTL常用标签及语法
    .ftl文件介绍
    maven之clean、install命令
    tomcat环境变量详细配置步骤
  • 原文地址:https://www.cnblogs.com/ghcred/p/9497432.html
Copyright © 2020-2023  润新知