• ABC208


    B

    题意:有1!, 2!, ..., 10!面值的硬币每个100个,问需要凑成P的最少的硬币数

    方法:贪心

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    
    using namespace std;
    
    int fac[11];
    
    int main(){
        fac[0] = 1;
        for(int i = 1; i <= 10; i ++) fac[i] = fac[i - 1] * i;
        
        int p;
        cin >> p;
        
        int res = 0;
        for(int i = 10; i >= 1; i --){
            if(p == 0) break;
            int cnt = min(p / fac[i], 100);
            res += cnt;
            p -= cnt * fac[i];
        }
        
        cout << res;
    }
    

    C

    题意:输入N个人,每个人有一个id,现在有K个糖,如果K比N大,给每个人一个,如果在某一次操作后K小于N,那么给id排名在1~K的所有人一个糖,问第i个人有多少糖(i = 1, 2, ... N)

    方法:每个人的基本糖数为k / n, 为每一个人保存序号和id,然后根据id升序排序,然后给前k个人多分一个糖,最后按照序号升序排序,输出答案

    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define int long long
    
    const int N = 2e5 + 10;
    
    struct node{
        int id, pos, val;
    }a[N];
    
    int n, k;
    
    int cmp1(const node &n1, const node &n2){
        return n1.id < n2.id;
    }
    
    int cmp2(const node &n1, const node &n2){
        return n1.pos < n2.pos;
    }
    
    signed main(){
        cin >> n >> k;
        for(int i = 0; i < n; i ++){
            int id;
            cin >> id;
            a[i] = {id, i};
        }
        
        sort(a, a + n, cmp1);
        int p = k % n, q = k / n;
        for(int i = 0; i < n; i ++) a[i].val = q + (i < p);
        sort(a, a + n, cmp2);
        for(int i = 0; i < n; i ++) cout << a[i].val << endl;
    }
    

    D

    题意:给你一个有向图,问

    [sum_{i=1}^{n}sum_{j=1}^{n}sum_{k=1}^{n}f(i, j, k) ]

    其中f(i, j, k)是从i到j只经过结点1~k的最短路径

    状态转移:根据i到j的只经过结点1~k的最短路径是否经过k来划分状态,不经过k的最短路为(f(i, j, k-1)), 经过k的最短路为(f(i, k, k - 1) + f(k, j, k - 1))

    所以(f(i, j, k) = min(f(i, j, k - 1), f(k, j, k - 1)))

    初始条件:(f(i, i, 0) = 0, i = 1,...,n)(f(a, b, 0) = c)其中a可以直接到b且权值为c,其他情况(f(i, j, *) = inf)(注意inf要足够大),另外空间可以用滚动数组优化...(开三维数组本地re)

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    
    using namespace std;
    
    #define int long long
    
    const int N = 410, INF = 0x3f3f3f3f3f3f3f3f;
    
    int n, m;
    int f[N][N][2];
    
    // f[s][t][k] = min(f[s][t][k - 1], f[s][k][k - 1] + f[k][t][k - 1])
    
    // f[s][k][k] f[k][t][k]
    
    // f[s][k][k] = min(f[s][k][k - 1], f[s][k][k - 1] + f[k][k][k - 1])
    // f[k][t][k] = min(f[k][t][k - 1], f[k][k][k - 1] + f[k][t][k - 1])
    
    
    signed main(){
        memset(f, 0x3f, sizeof f);
        
        cin >> n >> m;
        for(int i = 0; i < m; i ++){
            int a, b, c;
            cin >> a >> b >> c;
            f[a][b][0] = c;
        }
        
        for(int i = 1; i <= n; i ++)
            f[i][i][0] = 0;
        
        int res = 0, cur = 1, pre = 0;
        for(int k = 1; k <= n; k ++){
            for(int i = 1; i <= n; i ++)
                for(int j = 1; j <= n; j ++){
                    f[i][j][cur] = min(f[i][j][pre], f[i][k][pre] + f[k][j][pre]);
                    if(f[i][j][cur] < INF)
                        res += f[i][j][cur];
                }
            cur ^= 1, pre ^= 1;
        }
                
        cout << res;
    }
    
  • 相关阅读:
    转:算法的空间复杂度
    转:算法的最坏情况与平均情况 复杂度就要看最坏情况
    转:一些字符串函数的实现
    转:C语言字符串操作函数
    搜狐在线笔试 时间复杂度O(n)实现数组A[n]中所有元素循环左移k个位置
    搜狐笔试 最大连续递增子段和 关键词连续递增
    转:最小区间:k个有序的数组,找到最小区间使k个数组中每个数组至少有一个数在区间中
    转:strcpy实现的考察要点
    转:strcat与strcpy与strcmp与strlen
    转:多篇文章中的设计模式-------策略模式
  • 原文地址:https://www.cnblogs.com/tomori/p/15479932.html
Copyright © 2020-2023  润新知