zoukankan      html  css  js  c++  java
  • 《5.9训练部分题解》

    A:没写。

    B:没写。

    C:

    m个块来考虑,假设当前为[1,m]位置都站满了。

    现在我们要到[2,m + 1],如果a[1] > a[m + 1],跳过去之后a[m + 1]被站满。

    如果a[1] < a[m + 1]那么跳过去没被站满,那么剩下的只能有[2,m]来填充。

    那么综上所诉我们的答案就是所以m个块的和的最小值。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    const int N = 1e6 + 5;
    const int M = 2000 + 5;
    const LL Mod = 10007;
    #define pi acos(-1)
    #define INF 1e18
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO {
    inline LL read() {
        LL x = 0, f = 1;
        char c = getchar();
    
        while (c < '0' || c > '9') {
            if (c == '-')
                f = -1;
    
            c = getchar();
        }
    
        while (c >= '0' && c <= '9') {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
    
        return x * f;
    }
    }
    using namespace FASTIO;
    
    LL a[N];
    int main() {
        int n,m;n = read(),m = read();
        for(int i = 1;i < n;++i) a[i] = read();
        LL sum = 0;
        for(int i = 1;i <= m;++i) sum += a[i];
        LL ans = sum;
        for(int i = m + 1;i < n;++i) {
            sum -= a[i - m];
            sum += a[i];
            ans = min(ans,sum);
        }
        printf("%lld
    ",ans);
    
        return 0;
    }
    View Code

    D:

    dp[i][j][k] - 到i修改了j次,第i个位置以k为结尾的最优解

    枚举前一个位置是什么然后转移即可。

    注意用滚动数组压缩空间。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    const int N = 1e5 + 5;
    const int M = 350;
    const LL Mod = 1e9 + 7;
    #define pi acos(-1)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO {
    inline LL read() {
        LL x = 0, f = 1;
        char c = getchar();
    
        while (c < '0' || c > '9') {
            if (c == '-')
                f = -1;
    
            c = getchar();
        }
    
        while (c >= '0' && c <= '9') {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
    
        return x * f;
    }
    }
    using namespace FASTIO;
    
    int dp[2][505][30];//dp[i][j][k] - 到i修改了j次,第i个位置以k为结尾的最优解
    int main() {
        int n,t;
        n = read(),t = read();
        string s;cin >> s;
        memset(dp,0x3f3f3f,sizeof(dp));
        for(int k = 0;k < 26;++k) {
            int x = s[0] - 'a';
            if(x == k) {
                dp[1][0][x] = 1;
            }
            else {
                dp[1][1][k] = 1;
            }
        }
        for(int i = 2;i <= n;++i) {
            memset(dp[i % 2],0x3f3f3f,sizeof(dp[i % 2]));
            for(int j = 0;j <= t;++j) {
                if(j > t) break;
                int x = s[i - 1] - 'a';
                for(int k = 0;k < 26;++k) {
                    if(x == k) {
                        dp[i % 2][j][k] = min(dp[i % 2][j][k],dp[(i + 1) % 2][j][k]);
                    }
                    else {
                        if(j > 0) {
                            dp[i % 2][j][k] = min(dp[i % 2][j][k],dp[(i + 1) % 2][j - 1][k]);
                        }
                        dp[i % 2][j][x] = min(dp[i % 2][j][x],dp[(i + 1) % 2][j][k] + 1);
                    }
                }
            }
        }
        int ans = INF;
        for(int j = 0;j <= t;++j) {
            for(int k = 0;k < 26;++k) {
                ans = min(ans,dp[n % 2][j][k]);
            }
        }
        printf("%d
    ",ans);
      //  system("pause");
        return 0;
    }
    View Code

    E:

    对于每个数只有三种操作,1-加入总和,2-变阶乘后加入总和,3-不加入总和。

    那么复杂度就是3^n,显然这里会TLE,我们折半搜,先算前半部分,然后map存值。

    再搜后半部分顺便统计答案,复杂度3^(n / 2)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<LL, int> pii;
    const int N = 1e6 + 5;
    const int M = 2000 + 5;
    const LL Mod = 10007;
    #define pi acos(-1)
    #define INF 1e18
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO {
    inline LL read() {
        LL x = 0, f = 1;
        char c = getchar();
    
        while (c < '0' || c > '9') {
            if (c == '-')
                f = -1;
    
            c = getchar();
        }
    
        while (c >= '0' && c <= '9') {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
    
        return x * f;
    }
    }
    using namespace FASTIO;
    
    int n,k;
    LL s,ans = 0,f[20],a[30],dp[30][30];
    map<LL,int> mp[30];
    void init() {
        f[1] = 1;
        for(int i = 2;i <= 19;++i) f[i] = f[i - 1] * i;
    }
    
    void dfs(int x,int num,LL sum) {
        if(x == n / 2 + 1) {
         //   printf("%d %lld
    ",k - num,sum);
            mp[k - num][sum]++;
            return ;
        }
        if(sum + a[x] <= s) dfs(x + 1,num,sum + a[x]);
        if(a[x] <= 19 && sum + f[a[x]] <= s && num > 0) dfs(x + 1,num - 1,sum + f[a[x]]);
        dfs(x + 1,num,sum + 0);
    }
    void dfs2(int x,int num,LL sum) {
        if(x == n + 1) {
            for(int i = 0;i <= num;++i) {
                ans += mp[i][s - sum];
            }
            return ;
        }
        if(sum + a[x] <= s) dfs2(x + 1,num,sum + a[x]);
        if(a[x] <= 19 && sum + f[a[x]] <= s && num > 0) dfs2(x + 1,num - 1,sum + f[a[x]]);
        dfs2(x + 1,num,sum + 0);
    }
    int main() {
        init();
        n = read(),k = read(),s = read();
        for(int i = 1;i <= n;++i) a[i] = read();
        dfs(1,k,0);
        dfs2(n / 2 + 1,k,0);
        printf("%lld
    ",ans);
      //  system("pause");
        return 0;
    }
    /*
    2 4 2
    2 2
    */
    View Code

    F:

    枚举第i位是什么数,然后dfs判断一下最大值。

    假设我们现在能取到的最大值是x,然后我们现在枚举的数是a[i],那么我们下一个枚举的数的范围肯定是a[i] ~ x + 1。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<LL, int> pii;
    const int N = 1e3 + 5;
    const int M = 2000 + 5;
    const LL Mod = 10007;
    #define pi acos(-1)
    #define INF 1e18
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO {
    inline LL read() {
        LL x = 0, f = 1;
        char c = getchar();
    
        while (c < '0' || c > '9') {
            if (c == '-')
                f = -1;
    
            c = getchar();
        }
    
        while (c >= '0' && c <= '9') {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
    
        return x * f;
    }
    }
    using namespace FASTIO;
    
    int n,m,ans,a[15],dp[N],tmp[N];
    void dfs(int x,int num,int sum,int limit) {
        dp[sum] = 1;
        if(x == limit) return ;
        for(int i = 0;i <= num;++i) {
            dfs(x + 1,num - i,sum + a[x] * i,limit);
        }
    }
    void solve(int x) {
        memset(dp,0,sizeof(dp));
        //for(int i = 1;i < x;++i) printf("%d%c",a[i],i == x - 1 ? '
    ' : ' ');
        dfs(1,m,0,x);
        int L = a[x - 1] + 1,r;
        for(int i = 1;;++i) {
            if(dp[i] == 0) {
                r = i;
                break;
            }
        }
        if(r - 1 > ans) {
            for(int i = 1;i < x;++i) tmp[i] = a[i];
            ans = r - 1;
        }
        if(x == n + 1 || r < L) return ;
        for(int i = L;i <= r;++i) {
            a[x] = i;
            solve(x + 1);
        }
    }
    int main() {
        n = read(),m = read();
        a[1] = 1;
        ans = 1;
        solve(2);
        for(int i = 1;i <= n;++i) printf("%d%c",tmp[i],i == n ? '
    ' : ' ');
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    G:简单题

    H:

    首先,这里除了两个对角线之外出发都是组成环。并且这些环都可以看成从第一行的某个位置出发形成的环。

    那么我们环的总个数就是n - 2 加上两个对角线2.一共只有n种不同性质的走法。

    所以我们可以n^2枚举两个人的走法。注意在处理走法的时候同时处理一下重复的位置。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<LL, int> pii;
    const int N = 1e5 + 5;
    const int M = 2000 + 5;
    const LL Mod = 10007;
    #define pi acos(-1)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO {
    inline LL read() {
        LL x = 0, f = 1;
        char c = getchar();
    
        while (c < '0' || c > '9') {
            if (c == '-')
                f = -1;
    
            c = getchar();
        }
    
        while (c >= '0' && c <= '9') {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
    
        return x * f;
    }
    }
    using namespace FASTIO;
    
    int n,a[1005][1005],sum[1005],dir[1005][1005][5];
    int lp[1005][1005];
    bool vis[1005][1005];
    int main() {
        n = read();
        for(int i = 1;i <= n;++i)
            for(int j = 1;j <= n;++j) a[i][j] = read();
        for(int i = 1;i <= n;++i) {
            int nowx = 1,nowy = i,cx = 1,cy = 1,id = 1;
            if(i == n) cx = 1,cy = -1,id = 2;
            memset(vis,0,sizeof(vis));
            while(vis[nowx][nowy] == 0) {
                sum[i] += a[nowx][nowy];
                vis[nowx][nowy] = 1;
                dir[nowx][nowy][id] = i;
                for(int j = 1;j <= 4;++j) {
                    lp[i][dir[nowx][nowy][j]] += a[nowx][nowy];
                    lp[dir[nowx][nowy][j]][i] += a[nowx][nowy];
                }
                if(nowx == n && nowy == n) break;
                if(nowx == n && nowy == 1) break;
                nowx += cx,nowy += cy;
                if(nowy == n) {
                    cx = 1,cy = -1;
                    id = 2;
                }
                if(nowx == n) {
                    cx = -1,cy = -1;
                    id = 3;
                }
                if(nowx == 1) {
                    cx = 1,cy = 1;
                    id = 1;
                }
                if(nowy == 1) {
                    cx = -1,cy = 1;
                    id = 4;
                }
            }
        }
        int ans = 0;
        //or(int i = 1;i <= n;++i) printf("%d
    ",sum[i]);
        for(int i = 1;i <= n;++i) {
            for(int j = i + 1;j <= n;++j) {
                ans = max(ans,sum[i] + sum[j] - lp[i][j]);
            }
        }
        printf("%d
    ",ans);
      //  system("pause");
        return 0;
    }
    View Code

    I:

    可搜索可转压。

    我这里用了状压。

    dp[i][j]表示i状态下j营养的数量。

    转移就每次枚举一位没有的加入即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    const int N = 5e5 + 5;
    const int M = 2000 + 5;
    const LL Mod = 10007;
    #define pi acos(-1)
    #define INF 1e18 + 5
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO {
    inline int read() {
        int x = 0, f = 1;
        char c = getchar();
    
        while (c < '0' || c > '9') {
            if (c == '-')
                f = -1;
    
            c = getchar();
        }
    
        while (c >= '0' && c <= '9') {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
    
        return x * f;
    }
    }
    using namespace FASTIO;
    
    int a[30],b[20][30],ans[20],p[20],n;
    int dp[1 << 15][30];
    
    bool check(int x) {
        for(int i = 1;i <= n;++i) if(dp[x][i] < a[i]) return false;
        return true;
    }
    bool solve(int len) {
        for(int i = 1;i <= len;++i) {
            if(p[i] == ans[i]) continue;
            if(p[i] < ans[i]) return true;
            else return false;
        }
    }
    int main() {
        n = read();
        for(int i = 1;i <= n;++i) a[i] = read();
        int m;m = read();
        for(int i = 0;i < m;++i) {
            for(int j = 1;j <= n;++j) b[i][j] = read();
        }
        for(int i = 0;i < (1 << m);++i) {
            for(int j = 0;j < m;++j) {
                int g = ((i >> j) & 1);
                if(g == 0) {
                    int x = i | (1 << j);
                    for(int k = 1;k <= n;++k) {
                        dp[x][k] = dp[i][k] + b[j][k];
                    }
                }
            }
        }
        //for(int i = 0;i < (1 << m);++i)
            //for(int j = 1;j <= n;++j) printf("dp[%d][%d] is %d
    ",i,j,dp[i][j]);
        int len = 1000;
        for(int i = 0;i < (1 << m);++i) {
            if(check(i)) {
                int x = i,ta = 0;
                for(int j = 1;j <= m;++j) {
                    if(x % 2 != 0) p[++ta] = j;
                    x /= 2;
                }
                if(ta < len) {
                    len = ta;
                    x = i;
                    int f = 0;
                    for(int j = 1;j <= m;++j) {
                        if(x % 2 != 0) ans[++f] = j;
                        x /= 2;
                    }
                }
                else if(ta == len && solve(len)) {
                    x = i;
                    int f = 0;
                    for(int j = 1;j <= m;++j) {
                        if(x % 2 != 0) ans[++f] = j;
                        x /= 2;
                    }
                }
            }
        }
        printf("%d",len);
        for(int i = 1;i <= len;++i) printf(" %d",ans[i]);
        return 0;
    }
    /*
    4
    1250 200 300 400
    5
    100 200 300 400
    900 150 389 399
    200 300 200 300
    50  50  50  50
    500 120 150 300
    */
    View Code

    H:bfs即可。

    hash一下数字的状态来节省空间。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    const int N = 5e5 + 5;
    const int M = 2000 + 5;
    const LL Mod = 10007;
    #define pi acos(-1)
    #define INF 1e18 + 5
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO {
    inline int read() {
        int x = 0, f = 1;
        char c = getchar();
    
        while (c < '0' || c > '9') {
            if (c == '-')
                f = -1;
    
            c = getchar();
        }
    
        while (c >= '0' && c <= '9') {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
    
        return x * f;
    }
    }
    using namespace FASTIO;
    
    map<int,int> mp;
    int st,cnt = 0,pos0,b[4][2] = {1,0,-1,0,0,1,0,-1},a[10];
    struct Node{
        int x,step,pos;
    };
    int cal(int x) {
        if(x <= 3) return 1;
        else if(x <= 6) return 2;
        else return 3;
    }
    int cal2(int x) {
        if(x % 3 == 0) return 3;
        else return x % 3;
    }
    int cha(int x,int y) {
        int ma = 0;
        if(x == 1) ma += 0;
        else if(x == 2) ma += 3;
        else ma += 6;
        ma += y;
        return ma;
    }
    int bfs() {
        queue<Node> Q;
        Q.push(Node{st,0,pos0});
        while(!Q.empty()) {
            Node q = Q.front();
            Q.pop();
            if(q.x == 123804765) return q.step;
            int nowx = cal(q.pos),nowy = cal2(q.pos);
            int ta = q.x;
            //printf("ta is %d pos is %d
    ",ta,q.pos);
            for(int i = 9;i >= 1;--i) a[i] = ta % 10,ta /= 10;
            for(int i = 0;i < 4;++i) {
                int px = nowx + b[i][0];
                int py = nowy + b[i][1];
                if(px >= 1 && px <= 3 && py >= 1 && py <= 3) {
                    int ma = cha(px,py);
                    swap(a[q.pos],a[ma]);
                    int tmp = 0;
                    for(int i = 1;i <= 9;++i) tmp = tmp * 10 + a[i];
                    if(mp[tmp] == 0) {
                        mp[tmp] = ++cnt;
                        Q.push(Node{tmp,q.step + 1,ma});
                    }
                    swap(a[q.pos],a[ma]);
                }
            }
        }
    
    }
    
    
    int main() {
        st = read();
        mp[st] = ++cnt;
        int i = 9,ff = st;
        while(ff) {
            if(ff % 10 == 0) {
                pos0 = i;
                break;
            }
            ff /= 10;
            i--;
        }
        printf("%d
    ",bfs());
        return 0;
    }
    View Code
  • 相关阅读:
    卸载全部appx应用(包括应用商店)
    重置 Launchpad 和更新APP图标缓存
    删除OSX中第三方的「偏好设置」程序(.prefPane)
    IOS segue(跳转页面处理)
    IOS NSNotificationCenter(通知 的使用)监听文本框的文字改变
    IOS UITextFieldDelegate (常用的代理方法)
    IOS UIActionSheet(底部 弹出框的使用)
    IOS 偏好设置数据 存 取(Preferences文件夹)
    IOS plist的数据 存 取(沙河目录)
    显示 Mac隐藏的文件夹 命令语句
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/14753819.html
Copyright © 2011-2022 走看看