zoukankan      html  css  js  c++  java
  • 18.10.31 考试总结

    今天考试总算开始走入正轨了 早上强行逼着自己不去睡觉...。 把T1肝出来了... 不容易 T3是原题 最后二十分钟爆手速95分 少判了个重边

     

    这道题是一道推公式的题目 因为所有的格子都是由之前的格子推过来的 所以可以忽略中间部分的格子 只考虑给出的格子

    首先可以发现$(1, 1)$毫无用处 继续考虑每个格子的数向下之后会乘$b$向右乘$a$

    所以将格子初始考虑成水流将贡献分开计算 最终流向$(n, n)$

    每流一格自身的贡献会乘上一个系数并对这个格子产生贡献 所以考虑它有多少种产生贡献的方法 显然总的路程是知道的 

    所以路程数取一下组合数即可 他路径中的贡献就是$t * a^{x} * b^{y},x$是总路程中向右走的次数 $y$是向左走的次数$t$是初始值

    代码

    #include <bits/stdc++.h>
    #define il inline
    #define rg register
    using namespace std;
    
    typedef long long ll;
    const int N = 1e6 + 5;
    const ll MOD = 1e9 + 7;
    ll ans, fac[N], rfac[N], n, a, b;
    
    il ll read( ) {
        
        ll t = 1, ans = 0;
        char x; x = getchar( );
        while(x < '0' || x > '9') {
            if(x == '-') t - 1;
            x = getchar( );
        }
        while(x >= '0' && x <= '9') {
            ans = ans * 10 + x - '0';
            x = getchar( );
        }
        return ans * t;
    }
    
    il ll fast_pow(ll a, ll b) {
        
        ll ans = 1;
        for(;b;b >>= 1, a = a * a % MOD)
            if(b & 1) ans = ans * a % MOD;
        return ans;
    }
    
    il void Init( ) {
        
        n = read( ), b = read( ), a = read( );
        fac[0] = 1; rfac[0] = 1;
        for(rg int i = 1;i <= 2 * n;i ++) {
            fac[i] = fac[i - 1] * i % MOD;
            rfac[i] = fast_pow(fac[i], MOD - 2);
        }
    }
    
    il ll C(ll a, ll b) {
        
        if(b > a) return 0;
        return fac[a] * rfac[a - b] % MOD * rfac[b] % MOD; 
    }
    
    il void Solve( ) {
        
        for(rg int i = 1;i <= n;i ++) {
            ll t; t = read( );
            if(i == 1) continue;
            ll x = 2, y = i;
            ll len = n - x + n - y, lenb = n - x, lena = n - y;
            ll del = t * b % MOD * C(len, lenb) % MOD * fast_pow(b, lenb) % MOD * fast_pow(a, lena) % MOD;
            ans = (ans + del) % MOD;
        }
        for(rg int i = 1;i <= n;i ++) {
            ll t; t = read( );
            if(i == 1) continue;
            ll x = i, y = 2;
            ll len = n - x + n - y, lenb = n - x, lena = n - y;
            ll del = t * a % MOD * C(len, lenb) % MOD * fast_pow(b, lenb) % MOD * fast_pow(a, lena) % MOD;
            ans = (ans + del) % MOD;
        }
        printf("%lld
    ", ans);
    }
    
    int main( ) {
        
        freopen("matrix.in", "r", stdin);
        freopen("matrix.out", "w", stdout);
        Init( );
        Solve( );
    }

      

    这道题考试的时候觉得是贪心.. 但是这数据范围一看就不是贪心 所以就打了个暴搜

    使用记忆化搜索 首先发现取数的次数满足二分性 所以考虑二分

    每次搜索的时候对当前位置的数枚举它能够放$i$个$p$ 放$q$是有限制的 限制为$all - i$

    因为题目保证取出数的时候不能从一个数里取 所以这个数里取出$i$个$p$至少需要在外面的数取$i$个$q$

    也就是里面不能取超过$all - i$个$q$ 记忆化搜索即可 复杂度相当于填表 而且还填不满 略玄学

    代码

    #include <bits/stdc++.h>
    #define oo 1e6
    #define il inline
    #define rg register
    using namespace std;
    
    const int N = 1005;
    int n, p, q, a[N], sum[N], vis[51][N][N], idc, all;
    
    il int read( ) {
        
        int t = 1, ans = 0;
        char x; x = getchar( );
        while(x < '0' || x > '9') {
            if(x == '-') t - 1;
            x = getchar( );
        }
        while(x >= '0' && x <= '9') {
            ans = ans * 10 + x - '0';
            x = getchar( );
        }
        return ans * t;
    }
    
    void Init( ) {
        
        n = read( );
        if(p < q) swap(p, q);
        for(int i = 1;i <= n;i ++) a[i] = read( );
        p = read( ), q = read( );
        for(int i = n;i >= 1;i --) sum[i] = sum[i + 1] + a[i];
    }
    
    bool dfs(int dep, int nump, int numq) {
        
        if(! nump && ! numq) return true;
        if((dep == n + 1) || sum[dep] < nump * p + numq * q) return false;
        if(vis[dep][nump][numq] == idc) return false;
        for(int i = 0;i <= min(a[dep] / p, nump);i ++)
            if(dfs(dep + 1, nump - i, max(0, numq - min((a[dep] - i * p) / q, all - i)))) return true;
        vis[dep][nump][numq] = idc;
        return false;
    }
    
    bool check(int mid) {
        
        idc ++;
        all = mid;
        return dfs(1, mid, mid);
    }
    
    void Solve( ) {
        
        int l = 0, r = sum[1] / (p + q) + 1, ans = 0;
        while(l <= r) {
            int mid = l + r >> 1;
            if(check(mid)) ans = mid, l = mid + 1;
            else r = mid - 1;
        }
        printf("%lld", 1ll * ans * (p + q));
    }
    
    int main( ) {
        
        freopen("pq.in", "r", stdin);
        freopen("pq.out", "w", stdout);
        Init( );
        Solve( );
    }

     

      

    对不起这是一道原题..。 最后爆手速赶出来了

    多起点多重点$spfa$即可 记得判重边 我这里掉了五分

    代码

    #include <bits/stdc++.h>
    #define il inline
    #define rg register
    #define oo 1e9
    using namespace std;
    
    const int N = 3 * 1e4 + 5;
    const int M = 2 * 1e5 + 5;
    int n, m, head[N], nex[M], tov[M], val[M], tot = 1;
    int dis[N], ee[N], len[N], ans;
    bool vis[N];
    queue<int>Q;
    
    il int read( ) {
        
        int t = 1, ans = 0;
        char x; x = getchar( );
        while(x < '0' || x > '9') {
            if(x == '-') t - 1;
            x = getchar( );
        }
        while(x >= '0' && x <= '9') {
            ans = ans * 10 + x - '0';
            x = getchar( );
        }
        return ans * t;
    }
    
    il void add(int u, int v, int w) {
        
        tot ++; nex[tot] = head[u];
        tov[tot] = v; val[tot] = w; head[u] = tot;
    }
    
    il void Init( ) {
        
        n = read( ), m = read( );
        for(rg int i = 1;i <= m;i ++) {
            int u, v, w1, w2; u = read( ), v = read( ), w1 = read( ), w2 = read( );
            add(u, v, w1); add(v, u, w2);
        }
    }
    
    il void spfa(int st) {
        
        memset(dis, 0x3f3f3f3f, sizeof(dis));
        memset(vis, 0, sizeof(vis));
        memset(len, 0x3f3f3f3f, sizeof(len));
        for(rg int i = head[1];i;i = nex[i]) {
            int v = tov[i];
            len[v] = min(len[v], val[i ^ 1]);
            if(v & (1 << (st - 1))) {
                vis[v] = true; Q.push(v);
                dis[v] = min(dis[v], val[i]);
            } 
        }
        while(! Q.empty( )) {
            int u = Q.front( ); Q.pop( ); vis[u] = false;
            for(rg int i = head[u];i;i = nex[i]) {
                int v = tov[i]; if(v == 1) continue;
                if(dis[v] > dis[u] + val[i]) {
                    dis[v] = dis[u] + val[i];
                    if(! vis[v]) {
                        Q.push(v); vis[v] = true;
                    }
                }
            }
        }
        for(int i = head[1];i;i = nex[i]) {
            int v = tov[i]; 
            if(! (v & (1 << (st - 1)))) {
                ans = min(ans, dis[v] + len[v]);
            }
        }
        memset(dis, 0x3f3f3f3f, sizeof(dis));
        memset(vis, 0, sizeof(vis));
        for(rg int i = head[1];i;i = nex[i]) {
            int v = tov[i];
            len[v] = min(len[v], val[i ^ 1]);
            if(!(v & (1 << (st - 1)))) {
                vis[v] = true; Q.push(v);
                dis[v] = min(dis[v], val[i]);
            } 
        }
        while(! Q.empty( )) {
            int u = Q.front( ); Q.pop( ); vis[u] = false;
            for(rg int i = head[u];i;i = nex[i]) {
                int v = tov[i]; if(v == 1) continue;
                if(dis[v] > dis[u] + val[i]) {
                    dis[v] = dis[u] + val[i];
                    if(! vis[v]) {
                        Q.push(v); vis[v] = true;
                    }
                }
            }
        }
        for(rg int i = head[1];i;i = nex[i]) {
            int v = tov[i]; 
            if(v & (1 << (st - 1))) {
                ans = min(ans, dis[v] + len[v]);
            }
        }
    }
    
    int main( ) {
        
        freopen("graph.in", "r", stdin);
        freopen("graph.out", "w", stdout);
        Init( ); ans = oo; int h = 0;
        for(int i = head[1]; i; i = nex[i]) {
            int v = tov[i];
            for(int j = 30;j >= 1;j --) {
                if(v & (1 << (j - 1))) {
                    h = max(h, j); break;
                }
            }
        }
        for(int i = 1;i <= h;i ++) {
            spfa(i);
        }
        printf("%d
    ", ans);
    }
  • 相关阅读:
    Hihocoder 1275 扫地机器人 计算几何
    CodeForces 771C Bear and Tree Jumps 树形DP
    CodeForces 778D Parquet Re-laying 构造
    CodeForces 785E Anton and Permutation 分块
    CodeForces 785D Anton and School
    CodeForces 785C Anton and Fairy Tale 二分
    Hexo Next 接入 google AdSense 广告
    如何统计 Hexo 网站的访问地区和IP
    Design and Implementation of Global Path Planning System for Unmanned Surface Vehicle among Multiple Task Points
    通过ODBC接口访问人大金仓数据库
  • 原文地址:https://www.cnblogs.com/Rubenisveryhandsome/p/9883597.html
Copyright © 2011-2022 走看看