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);
    }
  • 相关阅读:
    99%的人都理解错了HTTP中GET与POST的区别
    CSS3 Border-image
    Tween.js的使用示例
    HTML5的postMessage使用记要
    Vuejs——(2)Vue生命周期,数据,手动挂载,指令,过滤器
    nodejs ejs 请求路径和静态资源文件路径
    JS逗号运算符的用法详解
    toStirng()与Object.prototype.toString.call()方法浅谈
    正则表达式之 贪婪与非贪婪模式
    利用符号进行的类型转换,转换成数字类型 ~~
  • 原文地址:https://www.cnblogs.com/Rubenisveryhandsome/p/9883597.html
Copyright © 2011-2022 走看看