zoukankan      html  css  js  c++  java
  • 【日更】蓝书第一章

    打完这个赛季(上个青),刷刷蓝书

    题目合集:

    https://cn.vjudge.net/article/737

    eg1:

    https://cn.vjudge.net/problem/UVA-11292

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<math.h>
    #include<ctime>
    #include<string>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int MAXN = 2e4 + 5;
    const int maxn = MAXN;
    const long long MOD = 1e8 + 7;
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    int phi[MAXN], prime[MAXN];
    
    int isntp[maxn];
    void sieve(int n) {
        int m = (int)sqrt(n + 0.5);
        mmm(isntp, 0);
        rep(i, 2, m)if (!isntp[i])for (int j = i * i; j <= n; j += i)isntp[j] = 1;
    
    }
    int ans[maxn];
    
    int smain();
    #define ONLINE_JUDGE
    int main() {
    
        //ios::sync_with_stdio(false);
    #ifndef ONLINE_JUDGE
        FILE *myfile;
        myfile = freopen("C:\Users\acm-14\Desktop\test\b.in", "r", stdin);
        if (myfile == NULL)
            fprintf(stdout, "error on input freopen
    ");
        FILE *outfile;
        outfile = freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout);
        if (outfile == NULL)
            fprintf(stdout, "error on output freopen
    ");
        long _begin_time = clock();
    #endif
        smain();
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        printf("time = %ld ms.", _end_time - _begin_time);
    #endif
        return 0;
    }
    int head[maxn];
    int cost[maxn];
    
    int smain()
    {
        int n, m;
        while (cin >> n >> m&&n) {
            rep(i, 1, n)cin >> head[i];
            rep(i, 1, m)cin >> cost[i];
            sort(head + 1, head + 1 + n);
            sort(cost + 1, cost + 1 + m);
            int p = 1;
            long long ans = 0;
            int f = 1;
            rep(i, 1, n) {
                if (p > m) {
                    f = 0; break;
                }
                while (head[i] > cost[p])p++;
                ans += cost[p],p++;
                
            }
            if (!f)puts("Loowater is doomed!");
            else cout << ans << endl;
        }
        
    
        /*don't delete*/
        return 0;
    }
    /*,
    2 3
    5
    4
    7
    8
    4
    2 1
    5
    5
    10
    0 0
    */
    View Code

    算法:无脑贪心+排序

    坑:本来想少写一个flag,结果想错了。。

    ps:静电容键盘到了,敲敲水题试一下。打字只要轻轻压(摸)一下就行,以至于手指经过别的键总是会碰到,也很容易打两次同一个字母,感觉习惯了的话代码速度可以上天。

    eg2

    https://cn.vjudge.net/problem/UVA-11729

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<math.h>
    #include<ctime>
    #include<string>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1e3 + 5;
    const int maxn = MAXN;
    const long long MOD = 1e8 + 7;
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define x first
    #define y second
    int phi[MAXN], prime[MAXN];
    
    int isntp[maxn];
    void sieve(int n) {
        int m = (int)sqrt(n + 0.5);
        mmm(isntp, 0);
        rep(i, 2, m)if (!isntp[i])for (int j = i * i; j <= n; j += i)isntp[j] = 1;
    
    }
    int ans[maxn];
    
    int smain();
    #define ONLINE_JUDGE
    int main() {
    
        //ios::sync_with_stdio(false);
    #ifndef ONLINE_JUDGE
        FILE *myfile;
        myfile = freopen("C:\Users\acm-14\Desktop\test\b.in", "r", stdin);
        if (myfile == NULL)
            fprintf(stdout, "error on input freopen
    ");
        FILE *outfile;
        outfile = freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout);
        if (outfile == NULL)
            fprintf(stdout, "error on output freopen
    ");
        long _begin_time = clock();
    #endif
        smain();
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        printf("time = %ld ms.", _end_time - _begin_time);
    #endif
        return 0;
    }
    int b[maxn], j[maxn];
    pair<int, int> p[maxn];
    int smain()
    {
        int n;
        int kase = 0;
        while (cin >> n && n) {
            printf("Case %d: ", ++kase);
            rep(i, 1, n) {
                cin >> p[i].y >> p[i].x;
            }
            sort(p + 1, p + 1 + n);
            int cur = 0;;
            int ans = 0;
            per(i,n,1) {
                cur += p[i].y;
                ans = max(ans, cur + p[i].x);
            }
            cout << ans << endl;
        }
    
        /*don't delete*/
        return 0;
    }
    /*,
    3
    2 5
    3 2
    2 1
    3
    3 3
    4 4
    5 5
    
    0 0
    */
    View Code

    算法:直觉贪心+排序

    ps:贪心的依据:ans=max(ans,cur+army[i].job)答案有这样的形式,cur是当前交待的总时间,考虑相邻的两个,总的cur是一样的,显然army.job短的人放在后面更优,所以就按照job降序排序了。

    电容键盘可以光速连按啊prprprprprprprprprrprprprprpprprprprprprprrprprrprprprprrprpprrpprprpr

    eg3‘

    https://cn.vjudge.net/problem/UVA-11300

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<math.h>
    #include<ctime>
    #include<string>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1e6 + 5;
    const int maxn = MAXN;
    const long long MOD = 1e9 + 7;
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define x first
    #define y second
    
    int smain();
    #define ONLINE_JUDGE
    int main() {
    
        //ios::sync_with_stdio(false);
    #ifndef ONLINE_JUDGE
        FILE *myfile;
        myfile = freopen("C:\Users\acm-14\Desktop\test\b.in", "r", stdin);
        if (myfile == NULL)
            fprintf(stdout, "error on input freopen
    ");
        FILE *outfile;
        outfile = freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout);
        if (outfile == NULL)
            fprintf(stdout, "error on output freopen
    ");
        long _begin_time = clock();
    #endif
        smain();
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        printf("time = %ld ms.", _end_time - _begin_time);
    #endif
        return 0;
    }
    long long A[maxn], C[maxn], tot, M;
    
    int smain()
    {
        int n;
        while (cin >> n) {
             tot = 0;
             rep(i, 1, n)scanf("%lld", &A[i]), tot += A[i];
             M = tot / n;
             C[0] = 0;
             rep(i, 1, n)C[i] = C[i - 1] + A[i] - M;
             sort(C, C + n);
             long long x1 = C[n / 2], ans = 0;
             for (int i = 0; i < n; i++) {
                 ans += abs(x1 - C[i]);
             }
             printf("%lld
    ", ans);
        }
    
        /*don't delete*/
        return 0;
    }
    /*,
    3
    100
    100
    100
    4
    1
    2
    5
    4
    
    */
    View Code

    算法:代数分析题 。中位数求方程组目标函数最值 

    ps:第一道代数题,,用一个for递推地算出系数,把系数存在数组c里,想不到想不到,

    eg4:

    https://cn.vjudge.net/problem/UVALive-3708

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<math.h>
    #include<ctime>
    #include<string>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1e6 + 5;
    const int maxn = MAXN;
    const long long MOD = 1e9 + 7;
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define x first
    #define y second
    
    int smain();
    #define ONLINE_JUDGE
    int main() {
    
        //ios::sync_with_stdio(false);
    #ifndef ONLINE_JUDGE
        FILE *myfile;
        myfile = freopen("C:\Users\acm-14\Desktop\test\b.in", "r", stdin);
        if (myfile == NULL)
            fprintf(stdout, "error on input freopen
    ");
        FILE *outfile;
        outfile = freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout);
        if (outfile == NULL)
            fprintf(stdout, "error on output freopen
    ");
        long _begin_time = clock();
    #endif
        smain();
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        printf("time = %ld ms.", _end_time - _begin_time);
    #endif
        return 0;
    }
    
    
    int smain()
    {
        int n, m;
        while (cin >> n >> m) {
            double ans = 0;
            rep(i, 1, n - 1) {
                double pos = (double)(n + m) / n * i;
                ans += abs(pos - floor(pos + 0.5))/(n+m);
            }
            printf("%.4lf
    ", ans * 10000);
        }
        /*don't delete*/
        return 0;
    }
    /*,
    3
    100
    100
    100
    4
    1
    2
    5
    4
    
    */
    View Code

    算法:几何想法 

    ps:四舍五入找最近点是真的sao

    eg5

    https://cn.vjudge.net/problem/UVA-10881

    算法:完全弹性碰撞的想法题(两个完全弹性碰撞的粒子可以看成互相穿过去!)+rank记录顺序技巧

    坑:sample output复制到vs里面被过滤掉了回车,然后输出格式错了orz。另外turning细节,前后两个一起赋值。

    #include <iostream>
    #include <vector>
    #include <cstdlib>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include<cstdio>
    #include<vector>
    #include<ctime>
    #include<string>
    #include<map>
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    const int maxn = 1e4 + 5;
    const double PI = acos(-1.0);
    struct ant {
        int x, rk;
        int dir;
    }a[maxn],b[maxn];
    bool cmp(ant a, ant b) { return a.x < b.x; }
    bool cmp2(ant a, ant b) { return a.rk < b.rk; }
    int main()
    {
        int kase = 0;
        int t; cin >> t; while (t--) {
            int l, time, n;
            cin >> l >> time >> n;
            rep(i, 1, n) {
                string S; int x;
                cin >> x >> S;
                a[i].x = x; a[i].dir = S == "R" ? 1 : -1;
                a[i].rk = i;
            }
            sort(a + 1, a + 1 + n,cmp);
            rep(i, 1, n) {
                b[i].x = a[i].x + a[i].dir * time;
                b[i].dir = a[i].dir;
                
            }
            sort(b + 1, b + 1 + n,cmp);
    
            rep(i, 1, n)b[i].rk = a[i].rk;
            rep(i, 1, n - 1)if (b[i].x == b[i + 1].x)b[i].dir =b[i+1].dir= 0;
            sort(b + 1, b + 1 + n, cmp2);
            printf("Case #%d:
    ", ++kase);
            rep(i, 1, n) {
                if (b[i].x<0 || b[i].x>l)puts("Fell off");
                else {
                    cout << b[i].x << ' ';
                    if (b[i].dir == 0)puts("Turning");
                    else puts(b[i].dir == 1 ? "R" : "L");
                }
            }
            cout << endl;
        }
        //cin >> t;
    }
    /*
    Sample Input
    2
    10 1 4
    1 R
    5 R
    3 L
    10 R
    10 2 3
    4 R
    5 L
    8 R
    
    
    Sample Output
    Case #1:
    2 Turning
    6 R
    2 Turning
    Fell off
    Case #2:
    3 L
    6 R
    10 R*/
    View Code

     eg6

    算法:贪心地做,蓝书上有证明,不怎么看得懂

    坑:i写成j,WF到底是WF

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    
    typedef double  db;
    typedef long long ll;
    const int MAXN = 12;;
    const int maxn = MAXN;
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    
    
    string view[maxn][maxn];
    int pos[maxn][maxn][maxn];
    int n;
    void get(int k, int i, int j, int len, int &x, int &y, int &z) {
        int nn = n - 1;
        if (k == 0) { x = len, z = i, y = j; }
        if (k == 1) { y = len, x = nn - j; z = i; }
        if (k == 2) { z = i, x = nn - len, y = nn - j; }
        if (k == 3) { z = i; x = j; y = nn - len; }
        if (k == 4) { x = nn - i, y = j, z = len; }
        if (k == 5) { y = j, x =  i, z = nn - len; }
    }
    
    int main() {
        
        while (cin >> n && n) {
            rep(i, 0, n - 1)rep(k, 0, 5) {
                cin >> view[k][i];
            }
            int nn = n - 1;
            rep(i, 0, nn)rep(j, 0, nn)rep(k, 0, nn)pos[i][j][k] = '#';
            int x = 0, y = 0, z = 0;
            rep(k, 0, 5)rep(i, 0,  nn)rep(j, 0, nn) {
                if (view[k][i][j] == '.') {
                    rep(d, 0, nn) {
                        get(k, i, j, d, x, y, z);
                        pos[x][y][z] = '.';
                    }
                }
            }
            while (1) {
                bool done = 1;
                
                rep(k, 0, 5)rep(i, 0, nn)rep(j, 0, nn)if (view[k][i][j] != 0) {
                    int bug = 1;
                    rep(d, 0, nn) {
                        get(k, i, j, d, x, y, z);
                        if (pos[x][y][z] == '.')continue;
                        if (pos[x][y][z] == '#') {
                            pos[x][y][z] = view[k][i][j];
                            {bug = 0; break; }
                        }
                        if (pos[x][y][z] == view[k][i][j]) {
                            bug = 0; break;
                        }
                        pos[x][y][z] = '.';
                        done = 0;
                    }
                    if (0) {
                        rep(i, 0, nn) { rep(j, 0, nn) { rep(k, 0, nn)cout << (char)pos[j][k][i]; cout << endl; }cout << endl; }
                        rep(i, 0, nn)cout << "---"; cout << endl;
                    }
                }
                if (done)break;
            }
            
            int ans = 0;
            rep(i, 0, nn)rep(j, 0, nn)rep(k, 0, nn)if (pos[i][j][k]!='.')ans++;
            //cout << ans << endl;
            printf("Maximum weight: %d gram(s)
    ", ans);
        }
    }
    /*
    3
    .R. YYR .Y. RYY .Y. .R.
    GRB YGR BYG RBY GYB GRB
    .R. YRR .Y. RRY .R. .Y.
    
    
    2
    ZZ ZZ ZZ ZZ ZZ ZZ
    ZZ ZZ ZZ ZZ ZZ ZZ
    0
    
    
    
    */
    View Code

     eg7

    https://cn.vjudge.net/problem/UVA-11464

    算法:暴力枚举n*n棋盘的第一行,然后递推地得出下面的每一行。

    坑:暴力算法写错*3  orz

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    
    typedef double  db;
    typedef long long ll;
    const int MAXN = 20;;
    const int maxn = MAXN;
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    const int INF = 1e9+10;
    int n;
    int a[maxn][maxn];
    int b[maxn][maxn];
    int check(int s) {
        int ret = 0;
        rep(i, 0, n-1) {
            if (((s&(1 << i)) != 0))b[1][i + 1] = 1; else b[1][i + 1] = 0;
            if (b[1][i + 1] == 0 && a[1][i + 1] == 1)return INF;
            else if (b[1][i + 1] != a[1][i + 1])ret++;
        }
        rep(i,2,n)
            rep(j, 1, n) {
            int prt = 0;
            //if (i - 2 < 1 || j - 1 < 1 || i + 1 > n)continue;
            if(i-1>=1&&j-1>=1)prt += b[i - 1][j - 1];
             if(i-1>=1&&j+1<=n)prt += b[i - 1][j + 1];
            if(i-2>=1)prt += b[i - 2][j];
            if (prt % 2 == 0) {
                if (a[i][j] == 1)return INF;
                 b[i][j] = 0;
            }
            else {
                if (a[i][j] == 0)ret++,b[i][j]=1;
                else b[i][j] = 1;
            }
        }
        return ret;
    }
    int main() {
        int t;
        cin >> t;
        int kase = 0;
        while (t--) {
            cin >> n;
            rep(i, 1, n)rep(j, 1, n)cin >> a[i][j];
            int ans = INF;
            rep (s, 0, (1 << n) - 1) {
                ans = min(ans, check(s));
                
                
            }
            if (ans == INF)ans = -1;
            printf("Case %d: %d
    ", ++kase, ans);
        }
        //cin >> t;
    }
    /*
    2
    3
    0 0 0
    1 0 0
    0 0 0
    
    
    3
    3
    0 0 0
    0 0 0
    0 0 0
    3
    0 0 0
    1 0 0
    0 0 0
    3
    1 1 1
    1 1 1
    0 0 0
    
    
    
    
    */
    View Code

     eg8 

    套路:骰子类的题套路(polya的群)。pose处理:写程序打表记录所有状态,动态地写。

    打表代码:

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 12e4;
    const db eps = 1e-7;
    const double PI = acos(-1.0);
    int l[] = { 4,0,2,3,5,1 };
    int up[] = { 2,1,5,0,4,3 };
    void rot(int * T, int * p) {
        int q[6];
        memcpy(q, p, sizeof(q));
        rep(i, 0, 5)p[i] = T[q[i]];
    }
    void print() {
        int p0[6] = { 0,1,2,3,4,5 };
        printf("int dice24[24][6]={
    ");
        rep(i, 0, 5) {
            int p[6];
            memcpy(p, p0, sizeof(p0));
            if (i == 0)rot(up, p);
            if (i == 1)rot(l, p), rot(up, p);
            if (i == 2);
            if (i == 3)rot(up, p), rot(up, p);
            if (i == 4)rot(l, p), rot(l, p), rot(l, p), rot(up, p);
            if (i == 5)rot(l, p), rot(l, p), rot(up, p);
            rep(i, 0, 3) {
                printf("{%d, %d, %d, %d, %d, %d},
     ", p[0], p[1], p[2], p[3], p[4], p[5]);
                rot(l, p);
            }
        }
        printf("};
    ");
    }
    int main() {
        int n;
        print();
        cin >> n;
    }
    /*
    
    
    */
    View Code

    AC代码:

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1005;
    const db eps = 1e-7;
    map<string,int>names;
    int dice[maxn][6];
    int n,ans,r[maxn];
    int color[maxn][6];
    int idx = 0;
    int dice24[24][6] = {
        { 2, 1, 5, 0, 4, 3 },
    { 2, 0, 1, 4, 5, 3 },
    { 2, 4, 0, 5, 1, 3 },
    { 2, 5, 4, 1, 0, 3 },
    { 4, 2, 5, 0, 3, 1 },
    { 5, 2, 1, 4, 3, 0 },
    { 1, 2, 0, 5, 3, 4 },
    { 0, 2, 4, 1, 3, 5 },
    { 0, 1, 2, 3, 4, 5 },
    { 4, 0, 2, 3, 5, 1 },
    { 5, 4, 2, 3, 1, 0 },
    { 1, 5, 2, 3, 0, 4 },
    { 5, 1, 3, 2, 4, 0 },
    { 1, 0, 3, 2, 5, 4 },
    { 0, 4, 3, 2, 1, 5 },
    { 4, 5, 3, 2, 0, 1 },
    { 1, 3, 5, 0, 2, 4 },
    { 0, 3, 1, 4, 2, 5 },
    { 4, 3, 0, 5, 2, 1 },
    { 5, 3, 4, 1, 2, 0 },
    { 3, 4, 5, 0, 1, 2 },
    { 3, 5, 1, 4, 0, 2 },
    { 3, 1, 0, 5, 4, 2 },
    { 3, 0, 4, 1, 5, 2 },
    };
    
    int ID(const char* name) {
        string s(name);
        if (names.count(s))return names[s];
        names[s] = ++idx; return names[s];
    }
    void check() {
        rep(i, 0, n-1)rep(j, 0, 5)color[i][dice24[r[i]][j]] = dice[i][j];
        int tot = 0;
        rep(j, 0, 5) {
            int cnt[maxn];
            mmm(cnt, 0);
            int maxface = 0;
            rep(i, 0, n-1)maxface = max(maxface, ++cnt[color[i][j]]);
            tot += n - maxface;
        }
        ans = min(ans, tot);
    }
    void dfs(int x) {
        if (x == n)check();
        else rep(i, 0, 23) {
            r[x] = i;
            dfs(x + 1);
        }
    }
    int main() {
        
        while (cin >> n && n)
        {
            names.clear(); idx = 0;
            rep(i, 0, n-1)rep(j, 0, 5) {
                char name[30];
                scanf("%s", name);
                dice[i][j] = ID(name);
            }
            ans = n * 6;
            r[0] = 0;
            dfs(1);
            cout << ans << endl;
        }
    }
    /*
    3
    scarlet green blue yellow magenta cyan
    blue pink green magenta cyan lemon
    purple red blue yellow cyan green
    2
    red green blue yellow magenta cyan
    cyan green blue yellow magenta red
    2
    red green gray gray magenta cyan
    cyan green gray gray magenta red
    2
    red green blue yellow magenta cyan
    magenta red blue yellow cyan green
    3
    red green blue yellow magenta cyan
    cyan green blue yellow magenta red
    magenta red blue yellow cyan green
    3
    blue green green green green blue
    green blue blue green green green
    green green green green green sea-green
    3
    red yellow red yellow red yellow
    red red yellow yellow red yellow
    red red red red red red
    4
    violet violet salmon salmon salmon salmon
    violet salmon salmon salmon salmon violet
    violet violet salmon salmon violet violet
    violet violet violet violet salmon salmon
    1
    red green blue yellow magenta cyan
    4
    magenta pink red scarlet vermilion wine-red
    aquamarine blue cyan indigo sky-blue turquoise-blue
    blond cream chrome-yellow lemon olive yellow
    chrome-green emerald-green green olive vilidian sky-blue
    0
    
    
    4
    2
    0
    0
    2
    3
    4
    4
    0
    16
    */
    View Code

     eg9

    套路:经典爆搜dfs。

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1005;
    const db eps = 1e-7;
    const char* mahjong[] = {
        "1T","2T","3T","4T","5T","6T","7T","8T","9T",
        "1S","2S","3S","4S","5S","6S","7S","8S","9S",
        "1W","2W","3W","4W","5W","6W","7W","8W","9W",
        "DONG","NAN","XI","BEI",
        "ZHONG","FA","BAI"
    };
    int convert(char *s) {
        REP(i, 0, 34) {
            if (strcmp(mahjong[i], s) == 0)return i;
        }
        return -1;
    }
    int cnt[34];
    bool search(int dep) {
        REP(i, 0, 34)if (cnt[i] >= 3) {
            if (dep == 3)return 1;
            cnt[i] -= 3;
            if (search(dep + 1))return 1;
            cnt[i] += 3;
        }
        rep(i, 0, 24)if (i % 9 <= 6 && cnt[i] >= 1 && cnt[i + 1] >= 1 && cnt[i + 2] >= 1) {
            if (dep == 3)return 1;
            cnt[i] -= 1, cnt[i + 1] -= 1, cnt[i + 2] -= 1;
            if (search(dep + 1))return 1;
            cnt[i] += 1, cnt[i + 1] += 1, cnt[i + 2] += 1;
        }
        return 0;
    
    }
    bool check() {
        REP(i, 0, 34) if (cnt[i] >= 2) {
                cnt[i] -= 2;
                if (search(0))return 1;
                cnt[i] += 2;
        }
        return 0;
    }
    int main() {
        int kase = 0;
        char s[100];
        int mj[15];
        bool ok=0;
        while (cin >> s) {
            if (s[0] == '0')break;
            printf("Case %d:", ++kase);
            mj[0] = convert(s);
            rep(i, 1, 12) { cin >> s; mj[i] = convert(s); }
            ok = 0;
            REP(i, 0, 34) {
                mmm(cnt, 0);
                REP(j, 0, 13)cnt[mj[j]]++;
                if (cnt[i] >= 4)continue;
                cnt[i]++;
                if (check()) {
                    ok = 1;
                    cout << ' '<<mahjong[i];
                }
                cnt[i]--;
            }
            if (!ok)puts(" Not ready");
            else cout << endl;
        }
    
    }
    /*
    
    */
    View Code

    eg10:

    https://cn.vjudge.net/problem/UVA-11384

    int f(int n) {
        return n == 1 ? 1 : f(n / 2) + 1;
    }
    int smain()
    {
        int n;
        while (cin >> n)cout << f(n) << endl;
    
        /*don't delete*/
        return 0;
    }
    View Code

    算法:经典瞎搞(想法)题

    ps:瞎搞入门啊

     eg11:

    套路:构建递归函数。汉诺塔类问题从最大的那个盘子考虑。

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1005;
    const db eps = 1e-7;
    int start[maxn], finish[maxn];
    ll f(int *P, int i, int final) {
        if (i == 0)return 0;
        if (P[i] == final)return f(P, i - 1, final);
        return f(P, i - 1, 6 - P[i] - final) + (1LL << (i - 1));
    }
    int main() {
        int kase = 0;
        int n;
        while (cin >> n && n) {
            rep(i, 1, n)cin >> start[i];
            rep(i, 1, n)cin >> finish[i];
            int k = n;
            while (k >= 1 && start[k] == finish[k])k--;
            long long ans = 0;
            if (k >= 1) {
                int other = 6 - start[k] - finish[k];
                ans = f(start, k - 1, other) + f(finish, k - 1, other) + 1;
            }
            printf("Case %d: %lld
    ", ++kase, ans);
        }
    
    }
    /*
    
    */
    View Code

    eg12:

    套路:最小值最大用二分。用map里套vector简化代码。还有注意二分的两种写法(表示自己并不明白)。

    坑:没买全 二分的判断函数要返回false,另外本题没有点明单调性(价格越高,品质越高) 虽然是常识,但也可能导致二分算法错(青岛的教训)

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1005;
    const db eps = 1e-7;
    map<string, vector<pair<int, int> > >mmp;
    int n, b;
    bool ok(int x) {
        int tot = 0;
        for (auto t : mmp) {
            int mn = 1e9 + 5;
            for (auto tt : t.second)if(tt.second>=x) {
                mn = min(mn, tt.first);
            }
            if (mn == 1e9 + 5)return false;
            tot += mn;
        }
        if (tot <= b)return true;
        else return false;
    }
    int main() {
        int T;
        cin >> T;
        while (T--) {
            mmp.clear();
            cin >> n >> b;
            int maxq = 0;
            rep(i, 1, n) {
                string s,ss;
                int p, q;
                cin >> s>>ss>>p>>q;
                maxq = max(maxq, q);
                mmp[s].push_back({ p,q });
            }
            
            int L = 0, R = maxq;
            while (L < R) {
                int mid = L + (R - L + 1) / 2;
                if (ok(mid))L = mid; else R = mid - 1;
            }
            cout << L << endl;
        }
        //cin >> T;
    }
    /*
    1
    18 800
    processor 3500_MHz 66 5
    processor 4200_MHz 103 7
    processor 5000_MHz 156 9
    processor 6000_MHz 219 12
    memory 1_GB 35 3
    memory 2_GB 88 6
    memory 4_GB 170 12
    mainbord all_onboard 52 10
    harddisk 250_GB 54 10
    harddisk 500_FB 99 12
    casing midi 36 10
    monitor 17_inch 157 5
    monitor 19_inch 175 7
    monitor 20_inch 210 9
    monitor 22_inch 293 12
    mouse cordless_optical 18 12
    mouse microsoft 30 9
    keyboard office 4 10
    
    */
    View Code

    eg13:

    https://cn.vjudge.net/problem/UVALive-3635

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<math.h>
    #include<ctime>
    #include<string>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1e5 + 5;
    const int maxn = MAXN;
    const long long MOD = 1e8 + 7;
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    int phi[MAXN], prime[MAXN];
    
    int isntp[maxn];
    void sieve(int n) {
        int m = (int)sqrt(n + 0.5);
        mmm(isntp, 0);
        rep(i, 2, m)if (!isntp[i])for (int j = i * i; j <= n; j += i)isntp[j] = 1;
    
    }
    int ans[maxn];
    
    int smain();
    #define ONLINE_JUDGE
    int main() {
    
        //ios::sync_with_stdio(false);
    #ifndef ONLINE_JUDGE
        FILE *myfile;
        myfile = freopen("C:\Users\acm-14\Desktop\test\b.in", "r", stdin);
        if (myfile == NULL)
            fprintf(stdout, "error on input freopen
    ");
        FILE *outfile;
        outfile = freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout);
        if (outfile == NULL)
            fprintf(stdout, "error on output freopen
    ");
        long _begin_time = clock();
    #endif
        smain();
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        printf("time = %ld ms.", _end_time - _begin_time);
    #endif
        return 0;
    }
    
    double a[maxn];
    int n, f;
    bool ok(double x) {
        int cnt = 0;
        rep(i, 1, n) {
            cnt += floor(a[i] / x);
        }
        return cnt >= f;
    }
    int smain()
    {
        int t; cin >> t;
        while (t--) {
            
            cin >> n >> f; f++;
            rep(i, 1, n)scanf("%lf", &a[i]),a[i]=a[i]*a[i]*acos(-1);
            double l = 0, r = 1e8*acos(-1);
            while (abs(l-r)> 1e-5) {
                double mid = (l + r) / 2;
                if (ok(mid))l = mid;
                else r = mid;
            }
            printf("%.5lf
    ", l);
        }
        return 0;
    }
    /*
    4
    3 3
    4 3 3
    1 24
    5
    10 5
    1 4 2 3 4 5 6 5 4 2
    */
    View Code

    算法:经典eps二分,

    坑点:输出cout会wa。改成了printf后忘记换行了orz

    ps:第一发写完发现和书上代码基本一样!

    eg14

    https://cn.vjudge.net/problem/UVA-11520

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<math.h>
    #include<ctime>
    #include<string>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1e5 + 5;
    const int maxn = MAXN;
    const long long MOD = 1e8 + 7;
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    int phi[MAXN], prime[MAXN];
    
    int isntp[maxn];
    void sieve(int n) {
        int m = (int)sqrt(n + 0.5);
        mmm(isntp, 0);
        rep(i, 2, m)if (!isntp[i])for (int j = i * i; j <= n; j += i)isntp[j] = 1;
    
    }
    int ans[maxn];
    
    int smain();
    #define ONLINE_JUDGE
    int main() {
    
        //ios::sync_with_stdio(false);
    #ifndef ONLINE_JUDGE
        FILE *myfile;
        myfile = freopen("C:\Users\acm-14\Desktop\test\b.in", "r", stdin);
        if (myfile == NULL)
            fprintf(stdout, "error on input freopen
    ");
        FILE *outfile;
        outfile = freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout);
        if (outfile == NULL)
            fprintf(stdout, "error on output freopen
    ");
        long _begin_time = clock();
    #endif
        smain();
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        printf("time = %ld ms.", _end_time - _begin_time);
    #endif
        return 0;
    }
    
    string s[11];
    int cnt[256];
    int n;
    char get(int x,int y) {
        mmm(cnt, 0);
        char ret = 0;
        rep(i,-1,1)
            rep(j, -1, 1)if(abs(i)+abs(j)<2) {
            int dx = x + i, dy = y + j;
            if (dx >= 0 && dx < n&&dy >= 0 && dy < n) {
                //if (s[dx][dy] == '.')ret = max((int)ret, 'A' - 1);
                cnt[s[dx][dy]]++;
            }
        }
        rep(i, 'A', 'Z')if (!cnt[i])return i;
        
    }
    int smain()
    {
        int t; cin >> t;
        int kase = 0;
        while (t--) {
            printf("Case %d:
    ", ++kase);
             cin >> n;
            rep(i, 0, n-1) {
                cin >> s[i];
            }
            rep(i, 0, n-1) 
                rep(j, 0, n-1)if(s[i][j]=='.') {
                 s[i][j] = get(i,j);
            }
            rep(i, 0, n-1)cout << s[i] << endl;
        }
        return 0;
    }
    /*
    3
    3
    ..B
    ...
    ...
    3
    B..
    ...
    ..A
    
    
    3
    3
    ...
    .C.
    Z..
    3
    ...
    A.X
    ...
    
    */
    View Code

    算法:了解一下字典序,书上的get函数有一点剪枝的

    坑点:string输入 循环是到n-1!

    ps:Morass 大佬也刷uva, 另外uva不把文件输入删掉也能ac啊?

    eg15 

    https://cn.vjudge.net/problem/UVALive-3902

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<math.h>
    #include<ctime>
    #include<string>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1e3 + 5;
    const int maxn = MAXN;
    const long long MOD = 1e8 + 7;
    #define rep(i,t,n)  for(int i =(t);i<=(n);++i)
    #define per(i,n,t)  for(int i =(n);i>=(t);--i)
    #define mmm(a,b) memset(a,b,sizeof(a))
    int phi[MAXN], prime[MAXN];
    
    int isntp[maxn];
    void sieve(int n) {
        int m = (int)sqrt(n + 0.5);
        mmm(isntp, 0);
        rep(i, 2, m)if (!isntp[i])for (int j = i * i; j <= n; j += i)isntp[j] = 1;
    
    }
    int ans[maxn];
    
    int smain();
    #define ONLINE_JUDGE
    int main() {
    
        //ios::sync_with_stdio(false);
    #ifndef ONLINE_JUDGE
        FILE *myfile;
        myfile = freopen("C:\Users\acm-14\Desktop\test\b.in", "r", stdin);
        if (myfile == NULL)
            fprintf(stdout, "error on input freopen
    ");
        FILE *outfile;
        outfile = freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout);
        if (outfile == NULL)
            fprintf(stdout, "error on output freopen
    ");
        long _begin_time = clock();
    #endif
        smain();
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        printf("time = %ld ms.", _end_time - _begin_time);
    #endif
        return 0;
    }
    
    vector<int> E[maxn], nodes[maxn];
    int n, s, k, fa[maxn];
    bool covered[maxn];
    void dfs(int u, int f, int d) {
        fa[u] = f;
        int nc = E[u].size();
        if (nc == 1 && d > k)nodes[d].push_back(u);
    
        for (int i = 0; i < nc; i++) {
            int v = E[u][i];
            if (v != f)dfs(v, u, d + 1);
        }
    }
    void dfs2(int u, int f, int d) {
        covered[u] = 1;
        int nc = E[u].size();
    
        for (int i = 0; i < nc; i++) {
            int v = E[u][i];
            if (v != f && d < k)dfs2(v, u, d + 1);
            
        }
    }
    int solve() {
        int ans = 0;
        mmm(covered, 0);
        for(int d=n-1;d>k;d--)
            for (int i = 0; i < nodes[d].size(); i++) {
                int u = nodes[d][i];
                if (covered[u])continue;
    
                int v = u;
                for (int j = 0; j < k; j++)v = fa[v];
                dfs2(v, -1, 0);
                ans++;
            }
        return ans;
    }
    int smain()
    {
        int t; cin >> t;
        while (t--)
        {
            cin >> n >> s >> k;
            rep(i, 1, n)E[i].clear(), nodes[i].clear();
            rep(i, 1, n-1) {
                int x, y;
                cin >> x >> y;
                E[x].push_back(y);
                E[y].push_back(x);
            }
            dfs(s, -1, 0);
            cout << solve() << endl;
        }
        cin >> t;
        return 0;
    }
    /*
    2 14
    12 2
    1 2
    2 3
    3 4
    4 5
    5 6
    7 5
    8 5
    4 9
    10 3
    2 12
    12 14
    13 14
    14 11
    14
    3 4
    1 2
    2 3
    3 4
    4 5
    5 6
    7 5
    8 5
    4 9
    10 3
    2 12
    12 14
    13 14
    14 11
    */
    View Code

    算法:树上贪心dfs暴力

    ps:蓝书的代码还是舒服啊

     eg16

    套路:想法+二分题收尾。二分是礼物种类越多越能满足分礼物约束,

    想法1是:先让第一个人取[1,a[i] ] 的礼物,然后在不取前一个人的前提下,偶数尽量往前取,奇数往后取,这样(当总人数为奇数时)最后一个是往后取的,判一下他有没有取到[1,a[i] ]的礼物就行。

    想法2是:如果我们建一个vis数组表示前一个人拿了几个,那算法就n^2logn 了 。我们考虑每一个人具体选了哪些不重要,重要的是选了几个,more precisely,要表达尽量往前取和往后取,我们只要把礼物分成前半部分与后半部分,以a[1]为分界,这样二分的judge函数就变成线性了

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1e5+5;
    const db eps = 1e-7;
    
    int n, b;
    int a[maxn];
    int vis[maxn] ;
    int l[maxn], r[maxn];
    bool ok(int p) {
        int x = a[1], y = p - x;
        l[1] = x; r[1] = 0;
        rep(i, 2, n) {
            if (i % 2 == 0)
            {
                l[i] = min(x - l[i - 1],a[i]);
                r[i] = a[i] - l[i];
            }
            else {
                r[i] = min(a[i], y - r[i - 1]);
                l[i] = a[i] - r[i];
            }
            
        }
        return l[n] == 0;
        
    }
    
    
    int main() {
        
        while (cin >> n && n) {
            
            int maxa=0;
            rep(i, 1, n)scanf("%d", &a[i]),maxa=max(maxa,a[i]);
            if (n == 1)cout << a[1] << endl;
            else{
                int ans = a[n] + a[1];
                rep(i, 1, n - 1)ans = max(ans, a[i] + a[i + 1]);
                
            
            
                int L = ans, R = maxa*4;
                if (n % 2) {
                    while (L <= R) {
    
                        int mid = L + R >> 1;
                        if (ok(mid))R = mid - 1; else L = mid + 1;
                    }
                }
                cout << L << endl;
            }
        }
            
            
            
        
        //cin >> T;
    }
    View Code

    eg17

    加速:计数排序

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1e5+5;
    const db eps = 1e-7;
    
    int cnt[101];
    int n;
    
    int main() {
    
        while (cin >> n && n) {
            int x;
            mmm(cnt, 0);
            rep(i, 1, n) {
                scanf("%d", &x); cnt[x]++;
            }
            int first = 1;
            rep(i, 1, 100) {
                while (cnt[i]--) {
                    if (first)printf("%d", i), first = 0;
                    else printf(" %d", i);
                }
            }
            cout << endl;
    
    
            //cin >> T;
        }
    }
    /*
    
    
    */
    View Code

    eg18

    加速:线性算法。O(1)存储动态维护max

    #include<algorithm>
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1e5+5;
    const db eps = 1e-7;
    
    int cnt[101];
    int n;
    
    int main() {
    
        int T;
        cin >> T;
        while(T--){
            int n;
            cin >> n;
            int a;
            
            int ans = -1e9;
            cin >> a;
            int maxa = a;
            rep(i, 2, n) {
                cin >> a;
                ans = max(ans, maxa - a);
                maxa = max(maxa, a);
            }
            cout << ans << endl;
            //cin >> T;
        }
        //cin >> T;
    }
    /*
    
    
    
    */
    View Code

     eg19

    加速:stl找循环节,截取技巧。

    套路:floyd判圈找循环节:比set快,O(1)。

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1e5+5;
    const db eps = 1e-7;
    
    int cnt[101];
    int n;
    int next(int n, int k) {
        stringstream ss;
        ss << (long long)k*k;
        string s = ss.str();
        if (s.length() > n)s = s.substr(0, n);
        int ans;
        stringstream ss2(s);
        ss2 >> ans;
        return ans;
    }
    set<int>S;
    int main() {
    
        int T;
        cin >> T;
        while(T--){
            int n,k;
            cin >> n>>k;
            S.clear();
            int ans = k;
            while (!S.count(k)) {
                S.insert(k);
                k = next(n, k);
                ans = max(ans, k);
            }
            cout << ans << endl;
        }
        //cin >> T;
    }
    /*
    2
    1 6
    2 99
    
    
    */
    View Code
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1e5+5;
    const db eps = 1e-7;
    
    int cnt[101];
    int n;
    int next(int n, int k) {
        stringstream ss;
        ss << (long long)k*k;
        string s = ss.str();
        if (s.length() > n)s = s.substr(0, n);
        int ans;
        stringstream ss2(s);
        ss2 >> ans;
        return ans;
    }
    set<int>S;
    int main() {
    
        int T;
        cin >> T;
        while(T--){
            int n,k;
            cin >> n>>k;
            S.clear();
            int k1 = k, k2 = k;
            int ans = k;
            do {
                k1 = next(n, k1);
                k2 = next(n, k2); ans = max(ans, k2); k2 = next(n, k2); ans = max(ans, k2);
            } while (k1 != k2);
            cout << ans << endl;
        }
        //cin >> T;
    }
    View Code

    一下是一系列递推维护区间(一维二维三维,单调性)信息的线性优化。,可以说是dp了

     eg20

    加速:线性找区间某点最大覆盖线段数。

    套路:解不等式组

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1e5+5;
    const db eps = 1e-7;
    //0<x+at<w
    void update(int x, int a, int w, double& L, double& R) {
        if (a == 0) {
            if (x <= 0 || x >= w)R = L - 1;
        }
        else if (a > 0) {
            L = max(L, -(double)x / a);
            R = min(R, (double)(w - x) / a);
        }
        else {
            L = max(L, (double)(w-x) / a);
            R = min(R, -(double)x / a);
        }
    }
    struct Event {
        double x;
        int type;
        bool operator <(const Event& a) const {
            return x < a.x || (x == a.x&&type > a.type);
        }
    }events[maxn*2];
    int main() {
    
        int T;
        cin >> T;
        while(T--){
            int w, h, n, e = 0;
            scanf("%d%d%d", &w, &h, &n);
            for (int i = 0; i < n; i++) {
                int x, y, a, b;
                scanf("%d%d%d%d", &x, &y, &a, &b);
                double L = 0, R = 1e9;
                update(x, a, w, L, R);
                update(y, b, h, L, R);
                if (R > L) {
                    events[e++] = { L, 0 };
                    events[e++]=  { R, 1 };
                }
            }
            sort(events, events + e);
            int cnt = 0;
            int ans = 0;
            REP(i, 0, e) {
                if (events[i].type == 0)ans = max(ans, ++cnt);
                else cnt--;
            }
            cout << ans << endl;
        }
        cin >> T;
    }
    /*
    2
    4 2
    2
    -1 1 1 -1
    5 2 -1 -1
    13 6
    7
    3 -2 1 3
    6 9 -2 -1
    8 0 -1 -1
    7 6 10 0
    11 -2 2 1
    -2 4 6 -1
    3 2 -5 -1
    
    
    */
    View Code

    eg21

    加速:利用单调性,二分nlogn 再到线性 n

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1e5+5;
    const db eps = 1e-7;
    //0<x+at<w
    int a[maxn],s[maxn];
    int main() {
        int n, S;
        
        while (cin >> n >> S) {
            int ans = 1e6;
            rep(i, 1, n)scanf("%d", &a[i]);
            rep(i, 1, n)s[i] = s[i - 1] + a[i];
            rep(j, 1, n) {
                int i = lower_bound(s, s + j, s[j] - S) - s;
                if (i > 0)ans = min(ans, j - i + 1);
            }
            if (ans == 1e6)ans = 0;
            cout << ans<<endl;
        }
    }
    /*
    10 15
    5 1 3 5 10 7 4 9 2 8
    5 11
    1 2 3 4 5
    
    
    
    */
    View Code
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 100010;;
    const int maxn = 1e5+5;
    const db eps = 1e-7;
    //0<x+at<w
    int a[maxn],s[maxn];
    int main() {
        int n, S;
        
        while (cin >> n >> S) {
            int ans = 1e6;
            rep(i, 1, n)scanf("%d", &a[i]);
            rep(i, 1, n)s[i] = s[i - 1] + a[i];
            int i = 1;
            rep(j, 1, n) {
                if (s[i - 1] > s[j] - S)continue;
                while (s[i] < s[j] - S)i++;
                ans = min(ans,j - i + 1);
            }
            if (ans == 1e6)ans = 0;
            cout << ans<<endl;
        }
    }
    /*
    10 15
    5 1 3 5 10 7 4 9 2 8
    5 11
    1 2 3 4 5
    
    
    
    */
    View Code

    eg22

    加速:维护二维网格里的最大矩阵:维护每个各点向上延申最远点,以及这条线段左右移动的最远点。

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 1010;;
    const int maxn = 1e3+5;
    const db eps = 1e-7;
    
    int a[maxn],s[maxn];
    int mat[maxn][maxn], up[maxn][maxn], l[maxn][maxn], r[maxn][maxn];
    int main() {
        int t; cin >> t; while (t--) {
            int n, m;
            cin >> n >> m;
            rep(i, 1, n)
                rep(j, 1, m) {
                char c = getchar();
                while (c != 'F'&&c != 'R') { c = getchar(); }
                mat[i][j] = c == 'F' ? 0 : 1;
            }
            int ans = 0;
            rep(i, 1, n) {
                int lo = 0, ro = m+1;
                rep(j, 1, m)if (mat[i][j] == 1)up[i][j] = l[i][j] = 0, lo = j;
                else {
                    up[i][j] = i == 1 ? 1 : up[i - 1][j] + 1;
                    l[i][j] = i == 1 ? lo + 1 : max(l[i - 1][j], lo + 1);
                }
                per(j, m, 1) if (mat[i][j] == 1)r[i][j] = m + 1, ro = j; else {
                    r[i][j] = i == 1 ? ro - 1 : min(r[i - 1][j], ro - 1);
                    ans = max(ans, up[i][j] * (r[i][j] - l[i][j] + 1));
                }
            }
            cout << ans * 3<<endl;
        }
        //cin >> t;
    }
    /*
    2
    5 6
    R F F F F F
    F F F F F F
    R R R F F F
    F F F F F F
    F F F F F F
    5 5
    R R R R R
    R R R R R
    R R R R R
    R R R R R
    R R R R R
    
    
    */
    View Code

     eg23

    题意:给你一堆点,计算在一个矩形边长上的点数最大值。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

    加速:y坐标离散化。把矩形拆成两条横线两条竖线。横线用前缀和维护,竖线暴力维护。线性时间,再加上枚举上下界,O(n^3).

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 110;;
    const int maxn = 1e2+5;
    const db eps = 1e-7;
    struct Point {
        int x, y;
        bool operator<(const Point& a)const {
            return x < a.x;
        }
    }p[maxn];
    int n, m, y[maxn], on[maxn], on2[maxn], l[maxn];
    int solve() {
        sort(p, p + n);
        sort(y, y + n);
        m = unique(y, y + n) - y;//离散化
        if (m <= 2)return n;
        int ans = 0;
        REP(a, 0, m)
            REP(b, a + 1, m) {
            int ymin = y[a], ymax = y[b];
    
            int k = 0;
            REP(i, 0, n) {
                if (i == 0 || p[i].x != p[i - 1].x) {
                    k++;
                    on[k] = on2[k] = 0;
                    l[k] =  l[k - 1] + on2[k - 1] - on[k - 1];
                }
                if (p[i].y > ymin&&p[i].y < ymax) on[k]++;
                if (p[i].y >= ymin && p[i].y <= ymax) on2[k]++;
            }
            if (k <= 2)return n;
            
            int M = 0;
            rep(j, 1, k) {
                ans = max(ans, l[j] + on2[j] + M);
                M=max(M, on[j] - l[j]);
            }
        }
        return ans;
    }
    int main() {
        int kase = 0;
        while (cin >> n && n)
        {
            REP(i, 0, n) { cin >> p[i].x >> p[i].y; y[i] = p[i].y; }
            printf("Case %d: %d
    ", ++kase, solve());
        }
    }
    /*
    10
    2 3
    9 2
    7 4
    3 4
    5 7
    1 5
    10 4
    10 6
    11 4
    4 6
    0
    
    
    
    */
    View Code

     eg24

    加速:三维前缀和 , 具体原理也不怎么明白,当个板子用就好了

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 30;;
    const int maxn = 1e2+5;
    const db eps = 1e-7;
    ll S[maxn][maxn][maxn];
    ll INF = 1ll << 60;
    void expand(int i, int& b0, int& b1, int& b2) {
        b0 = i & 1; i >>= 1;
        b1 = i & 1; i >>= 1;
        b2 = i & 1;
    }
    int sign(int b0, int b1, int b2) {
        return (b0 + b1 + b2) % 2 == 1 ? 1 : -1;
    }
    ll sum(int x1, int x2, int y1, int y2, int z1, int z2) {
        int dx = x2 - x1 + 1; int dy = y2 - y1 + 1; int dz = z2 - z1 + 1;
        ll s = 0;
        rep(i, 0, 7) {
            int b0, b1, b2;
            expand(i, b0, b1, b2);
            s -= S[x2 - b0 * dx][y2 - b1 * dy][z2 - b2 * dz] * sign(b0, b1, b2);
        }
        return s;
    }
    int main() {
        int t; cin >> t;
        while (t--) {
            int a, b, c, b1, b2, b0;
            cin >> a >> b >> c;
            mmm(S, 0);
            rep(x, 1, a)rep(y, 1, b)rep(z, 1, c)scanf("%lld", &S[x][y][z]);
            rep(x, 1, a)rep(y, 1, b)rep(z, 1, c)rep(i, 1, 7) {
                expand(i, b0, b1, b2);
                S[x][y][z] += S[x - b0][y - b1][z - b2] * sign(b0, b1, b2);
            }
            
            long long ans = -INF;
            rep(x1, 1, a)rep(x2, x1, a)rep(y1,1,b)rep(y2, y1, b) {
                long long M = 0;
                rep(z, 1, c) {
                    long long s = sum(x1, x2, y1, y2, 1, z);
                    ans = max(ans, s - M);
                    M = min(M, s);
                }
            }
            cout << ans << endl;
            if (t)cout << endl;
        }
        //cin >> t;
    }
    /*
    1
    2 2 2
    -1 2 0 -3 -2 -1 1 5
    
    
    */
    View Code

    eg25

    套路:用异或和压缩字符串,然后状压地2^n暴力,用map降低复杂度(中途相遇)O(2^(N/2)*logn)

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 30;;
    const int maxn = 24;
    const db eps = 1e-7;
    
    map<int, int>table;
    int bitcount(int x) { return x == 0 ? 0 : bitcount(x /2) + (x & 1); }//popcount
    int A[maxn];
    int main() {
        int n;
        while (cin >> n) {
            REP(i, 0, n) {
                string s; cin >> s;
                A[i] = 0;
                for (auto t : s) {A[i] ^= (1 << (t - 'A'));}
            }
            table.clear();
            int n1 = n / 2, n2 = n - n1;
            for (int i = 0; i < (1 << n1); i++) {
                int x = 0;
                REP(j, 0, n1)if (i & (1 << j))x ^= A[j];
                if (!table.count(x) || bitcount(table[x]) < bitcount(i))table[x] = i;
            }
            int ans = 0;
            for (int i = 0; i < (1 << n2); i++) {
                int x = 0;
                for (int j = 0; j < n2; j++)if (i&(1 << j))x ^= A[n1+j];
                if (table.count(x) && bitcount(ans) < bitcount(table[x]) + bitcount(i))ans = (i << n1) ^ table[x];
            }
            cout << bitcount(ans) << endl;
            REP(i, 0, n)if (ans&(1 << i))cout << i + 1<<' ';
            cout << endl;
            
        }
        //cin >> t;
    }
    /*
    1
    ABC
    6
    ABD
    EG
    GE
    ABE
    AC
    BCD
    
    */
    View Code

     eg26

    dp:约瑟夫递推地做

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 30;;
    const int maxn = 1e4+2;
    const db eps = 1e-7;
    int f[maxn];
    int main() {
        int n, m, k;
        while (cin >> n >> k >> m && n) {
            f[1] = 0;
            rep(i, 2, n)f[i] = (f[i - 1] + k) % i;
            int ans = (m - k + 1 + f[n]) % n;
            if (ans <= 0)ans += n;
            cout << ans << endl;
        }
    }
    /*
    8 5 3
    100 9999 98
    10000 10000 10000
    0 0 0
    
    */
    View Code

    eg27

    dp:LCS转化为LIS 具体做法是对第一个序列离散化,然后在第二个里LIS

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 30;;
    const int maxn = 250*250+2;
    const int INF = 1e9;
    const db eps = 1e-7;
    int S[maxn], g[maxn], d[maxn];
    int num[maxn];
    int main() {
        int T;
        cin >> T;
        rep(k, 1, T) {
            int N, p, q, x;
            cin >> N >> p >> q;
            rep(i, 1, p + 1) { scanf("%d", &x); num[x] = i; }
            int n = 0;
            rep(i, 0, q) {
                scanf("%d", &x); if (num[x])S[n++] = num[x];
            }
            rep(i, 1, n)g[i] = INF;
            int ans = 0;
            REP(i, 0, n) {
                int k = lower_bound(g + 1, g + n + 1, S[i]) - g;
                d[i] = k;
                g[k] = S[i];
                ans = max(ans, d[i]);
    
            }
            printf("Case %d: %d
    ", k, ans);
        }
    }
    /*
    1
    3 6 7
    1 7 5 4 8 3 9
    1 4 3 5 6 2 8 9
    
    */
    View Code

    eg28

    dp:d(i,j)=sum(i,j)-min{rep(x,i+1,j)d(x,j);per(x,j-1,i)d(i,x);0;}.

    优化:区间N*N dp 预处理成O(N)

    记忆化搜索:

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 30;;
    const int maxn = 100+2;
    const int INF = 1e9;
    const db eps = 1e-7;
    int n;
    int S[maxn], A[maxn], d[maxn][maxn], vis[maxn][maxn];
    int dp(int i, int j) {
        if (vis[i][j])return d[i][j];
        vis[i][j] = 1;
        int m = 0;
        rep(k, i + 1, j)m = min(m, dp(k,j));
        rep(k, i, j - 1)m = min(m, dp(i, k));
        d[i][j] = S[j] - S[i - 1] - m;
        return d[i][j];
    }
    int main() {
        while (cin >> n && n) {
            S[0] = 0;
            rep(i, 1, n){
                cin >> A[i]; S[i] = S[i - 1] + A[i];
            }
            mmm(vis, 0);
            cout << 2 * dp(1, n) - S[n] << endl;;
        }
    
    }
    /*
    4
    4 -10 -20 7
    4
    1 2 3 4
    0
    
    */
    View Code

    预处理:

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 30;;
    const int maxn = 100+2;
    const int INF = 1e9;
    const db eps = 1e-7;
    int n;
    int S[maxn], A[maxn], d[maxn][maxn], vis[maxn][maxn];
    int f[maxn][maxn], g[maxn][maxn];
    int dp(int i, int j) {
        if (vis[i][j])return d[i][j];
        vis[i][j] = 1;
        int m = 0;
        rep(k, i + 1, j)m = min(m, dp(k,j));
        rep(k, i, j - 1)m = min(m, dp(i, k));
        d[i][j] = S[j] - S[i - 1] - m;
        return d[i][j];
    }
    int main() {
        while (cin >> n && n) {
            S[0] = 0;
            rep(i, 1, n){
                cin >> A[i]; S[i] = S[i - 1] + A[i];
            }
            rep(i, 1, n)f[i][i] = g[i][i] = d[i][i] = A[i];
            rep(len, 1, n)
                rep(i, 1, n - len) {
                int j = i + len;
                int m = 0;
                m = min(m, f[i + 1][j]);
                m = min(m, g[i][j - 1]);
                d[i][j] = S[j] - S[i - 1] - m;
                f[i][j] = min(d[i][j], f[i + 1][j]);
                g[i][j] = min(d[i][j], g[i][j - 1]);
    
            }
            //mmm(vis, 0);
            //cout << 2 * dp(1, n) - S[n] << endl;;
            cout << 2 * d[1][n] - S[n] << endl;;
        }
    
    }
    /*
    4
    4 -10 -20 7
    4
    1 2 3 4
    0
    
    */
    View Code

    eg29

    存储方法:状压集合,
    dp:f(S)=max{f(S-S0)|S0是S的子集,cover[S0]为全集}+1;

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 30;;
    const int maxn = 100+2;
    const int INF = 1e9;
    const db eps = 1e-7;
    
    int P[20];
    int cover[(1<<20)];
    int f[(1 << 20)];
    int n;
    int kase = 0;
    int main() {
        while (cin >> n && n) {
            REP(i, 0, n) {
                int m, x;
                scanf("%d", &m);
                P[i] = 1 << i;
                while (m--) { scanf("%d", &x); P[i] |= (1 << x); }
            }
            REP(S, 0, (1 << n)) {
                cover[S] = 0;
                REP(i, 0, n) {
                    if (S&(1 << i))cover[S] |= P[i];
                }
            }
            f[0] = 0;
            int ALL = (1 << n) - 1;
            rep(S, 1, (1 << n) - 1) {
                f[S] = 0;
                for (int S0 = S; S0; S0 = (S0 - 1)&S)
                    if (cover[S0] == ALL)f[S] = max(f[S], f[S^S0] + 1);
            }
            printf("Case %d: %d
    ", ++kase, f[ALL]);
        }
    
    
    }
    /*
    3
    2 1 2
    2 0 2
    2 0 1
    4
    1 1
    1 0
    1 3
    1 2
    0
    
    
    */
    View Code

    eg30 

    双目标优化+树形dp

    dp方程比较复杂。

    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<stdlib.h>
    #include<string.h>
    #include<assert.h>
    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<queue>
    #include<string>
    #include<ctime>
    #include<stack>
    #include<map>
    #include<set>
    #include<list>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define debug(x) cerr<<#x<<" = "<<(x)<<endl
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    //#define x first
    //#define y second
    typedef double db;
    typedef long long ll;
    const int MAXN = 30;;
    const int maxn = 100+2;
    const int INF = 1e9;
    const db eps = 1e-7;
    vector<int> adj[1010];
    int vis[1010][2], d[1010][2], n, m;
    int dp(int i, int j, int f) {
        if (vis[i][j])return d[i][j];
        vis[i][j] = 1;
        int & ans = d[i][j];
        ans = 2000;
        for (int k = 0; k < adj[i].size(); k++)
            if (adj[i][k] != f)ans += dp(adj[i][k], 1, i);
        if (!j&&f >= 0)ans++;
    
        if (j || f < 0) {
            int sum = 0;
            for (int k = 0; k < adj[i].size(); k++)if (adj[i][k] != f)
                sum += dp(adj[i][k], 0, i);
            if (f >= 0)sum++;
            ans = min(ans, sum);
        }
                
                
        
        return ans;
        
    }
    int main() {
        int T, a, b;
        cin >> T;
        while (T--) {
            cin >> n >> m;
            REP(i, 0, n)adj[i].clear();
            REP(i, 0, m) {
                cin >> a >> b;
                adj[a].push_back(b);
                adj[b].push_back(a);
            }
            mmm(vis, 0);
            int ans = 0;
            REP(i, 0, n)if (!vis[i][0])ans += dp(i, 0, -1);
            cout << ans / 2000 << ' ' << m - ans % 2000 << ' ' << ans % 2000<<endl;
        }
    
    
    }
    /*
    2
    4 3
    0 1
    1 2
    2 3
    5 4
    0 1
    0 2
    0 3
    0 4
    
    
    */
    View Code

     eg

    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    SDN第二次作业
    事后诸葛亮
    SDN第一次上机作业
    个人作业——软件产品案例分析
    SDN第一次作业
    Alpha冲刺总结报告
    Alpha冲刺Day10
    Alpha冲刺Day9
    Alpha冲刺Day8
    Alpha冲刺Day7
  • 原文地址:https://www.cnblogs.com/SuuT/p/9925527.html
Copyright © 2011-2022 走看看