• XVII Open Cup named after E.V. Pankratiev. XXI Ural Championship


    C.Construction sets  二分答案 多重背包二进制优化 bitset检验

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    void fre()
    {
            freopen("c://test//input.in", "r", stdin);
            freopen("c://test//output.out", "w", stdout);
    }
    #define MS(x, y) memset(x, y, sizeof(x))
    #define ls o<<1
    #define rs o<<1|1
    typedef long long LL;
    typedef unsigned long long UL;
    typedef unsigned int UI;
    template <class T1, class T2>inline void gmax(T1 &a, T2 b)
    {
            if (b > a)
            {
                    a = b;
            }
    }
    template <class T1, class T2>inline void gmin(T1 &a, T2 b)
    {
            if (b < a)
            {
                    a = b;
            }
    }
    const int N = 55, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
    template <class T1, class T2>inline void gadd(T1 &a, T2 b)
    {
            a = (a + b) % Z;
    }
    int casenum, casei;
    int n, mn, mx;
    int m[N], c[N];
    bitset<10005>f;
    bool check(int K)
    {
            f.reset();
            f[0] = 1;
            for (int i = 1; i <= n; ++i)
            {
                    int tot = c[i] / K;
                    int g = 1;
                    LL v = m[i];
                    while (tot)
                    {
                            if (v > mx)
                            {
                                    break;
                            }
                            f |= f << v;  
                            /*!!!! 等价于:
                            for(int k=v;k<=10005;k++)
                            f[k]|=f[k-v];
                            !!!!*/
                            /*cout << "i:" << i << endl;
                            for (int i = 1; i <= mx; i++)
                            {
                                    cout << f[i] << " ";
                            }
                            cout << endl;*/
                            tot -= g;   //多重背包二进制优化
                            g = min(g * 2, tot); //多重背包二进制优化
                            v = (LL)m[i] * g;  //多重背包二进制优化
                    }
            }
            for (int j = mn; j <= mx; ++j)
            {
                    if (f[j])
                    {
                            return 1;
                    }
            }
            return 0;
    }
    int main()
    {
            //freopen("input.txt", "r", stdin);
            //freopen("output.txt", "w", stdout);
            while (~scanf("%d%d%d", &n, &mn, &mx))
            {
                    for (int i = 1; i <= n; ++i)
                    {
                            scanf("%d%d", &m[i], &c[i]);
                    }
                    int l = 0;
                    int r = 1e6;
                    while (l < r)
                    {
                            int mid = (l + r + 1) >> 1;
                            //cout << "mid:" << mid << endl;
                            if (check(mid))
                            {
                                    l = mid;
                            }
                            else
                            {
                                    r = mid - 1;
                            }
                    }
                    printf("%d
    ", l);
            }
    
            return 0;
    }
    View Code

    D.Dinner party  DP

    #include<cstdio>
    #include<bitset>
    using namespace std;
    const int N = 1010, M = 2010;
    int T, n, m, i, j, x, y, cnt;
    bitset<M>f[N];   //!!!! f[i][j]表示面积为i周长为j(目标周长的一半)是否有可能
    int f2[1050][2050];
    void solve()
    {
            scanf("%d%d", &n, &m);
            if (m % 2)   //!!!! 周长肯定是偶数
            {
                    puts("No");
                    return;
            }
            m /= 2;
            if (f[n][m] == 0)   //!!!!不可能
            {
                    puts("No");
                    return;
            }
            puts("Yes");    
            int cnt = 0;
            static int q[100000][2];
            while (n)
            {
                    int X = 0, Y = 0;
                    for (x = 1; x <= n; x++)
                    {
                            for (y = 1; y * x <= n; y++)
                                    if (x + y <= m)
                                            if (f[n - x * y][m - x - y])
                                            {
                                                    X = x, Y = y;
                                                    break;
                                            }
                            if (X)
                            {
                                    break;
                            }
                    }
                    q[++cnt][0] = X;
                    q[cnt][1] = Y;
                    n -= X * Y;
                    m -= X + Y;
            }
            printf("%d
    ", cnt);
            for (int i = 1; i <= cnt; i++)
            {
                    printf("%d %d
    ", q[i][0], q[i][1]);
            }
    }
    int main()
    {
            //freopen("input.txt", "r", stdin);
            //freopen("output.txt", "w", stdout);
            //scanf("%d%d",&n,&m);
            n = 1000;
            m = 2000;
            f[0][0] = 1;
            f2[0][0] = 1;
            for (i = 0; i <= n; i++)
                    for (x = 1; x + i <= n; x++)
                            for (y = 1; x * y + i <= n; y++)
                            {
                                    f[i + x * y] |= f[i] << (x + y);
                                    /*!!!!
                                    表示f[i+x*y] 与上 f[i]左移(乘上)x+y 等价于:
                                    for (int k = 0; k <= m - x - y; k++)
                                    {
                                            f2[i + x * y][k + x + y] |= f2[i][k];
                                    }
                                    !!!!*/
                            }
            scanf("%d", &T);
            while (T--)
            {
                    solve();
            }
    }
    View Code

    G.Glasses with solutions   折半搜索 把35个拆成两半 复杂度为C(2,2)*2*2^(35/2)

    #include<cstdio>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int N=40;
    int n,m,A,B,i,x,y,a[N];map<ll,ll>f;
    ll ans;
    void dfsl(int x,ll y){
        if(x==m){f[y]++;return;}
        dfsl(x+1,y+a[x]);
        dfsl(x+1,y);
    }
    void dfsr(int x,ll y){
        if(x==n){ans+=f[-y];return;}
        dfsr(x+1,y+a[x]);
        dfsr(x+1,y);
    }
    int main(){
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        scanf("%d%d%d",&n,&A,&B);
        for(i=0;i<n;i++){
            scanf("%d%d",&x,&y);
            a[i]=x*B-A*y;
        }
        m=n/2;
        dfsl(0,0);
        dfsr(m,0);
        ans--;
        printf("%lld",ans);
    }
    View Code

    H. Hamburgers 二进制压缩&枚举操作

    #include<cstdio>
    #include<cstring>
    #include<vector>
    using namespace std;
    const int N = 55555;
    int n, m, i, j, k, x, ans[N], mx[N], b[N];
    vector<int>a[N];
    bool v[(1 << 26) + 5];
    inline int get() //!!!!二进制压缩  把每个人的口味压缩成1<<26内的数
    {
            static char s[1000];
            scanf("%s", s);
            int t = 0, len = strlen(s);
            for (int i = 0; i < len; i++)
            {
                    t |= 1 << (s[i] - 'a'); //!!!!!!转换成二进制
            }
            return t;
    }
    inline void make(int x, int y)
    {
            for (int i = x; i; i = (i - 1)&x) //!!!!枚举每位1存在或不存在的情况
            {
                    v[i] = y;
            }
    }
    int main()
    {
            //freopen("input.txt", "r", stdin);
            //freopen("output.txt", "w", stdout);
            scanf("%d", &n);
            for (i = 1; i <= n; i++)
            {
                    scanf("%d", &k);
                    while (k--)
                    {
                            x = get();
                            a[i].push_back(x);
                    }
                    ans[i] = 1;
            }
            scanf("%d", &m);
            for (i = 1; i <= m; i++)
            {
                    scanf("%d", &k);
                    for (j = 1; j <= k; j++)
                    {
                            b[j] = get();
                    }
                    for (j = 1; j <= k; j++)
                    {
                            make(b[j], 1);  //!!!找出每种情况
                    }
                    for (j = 1; j <= n; j++)
                    {
                            int t = 0;
                            for (x = 0; x < a[j].size(); x++)
                                    if (v[a[j][x]])
                                    {
                                            t++;
                                    }
                            if (t > mx[j])
                            {
                                    mx[j] = t, ans[j] = i;//!!!!找出每个group最适应的店
                            }
                    }
                    for (j = 1; j <= k; j++)
                    {
                            make(b[j], 0);  //!!!相当于memset 把先前变为1的变回0
                    }
            }
            for (i = 1; i <= n; i++)
            {
                    printf("%d
    ", ans[i]);
            }
    }
    View Code

    J.Jumps through the Hyperspace   预处理+迪杰斯特拉

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    typedef pair<int, int>P;
    const int N = 2010, inf = ~0U >> 1;
    int n, m, st, i, j, a[N], b[N], c[N], d[N], w[N][N];
    int f[N];
    char g[N][N], op[N];
    priority_queue<P, vector<P>, greater<P> >q;
    inline void ext(int x, int y)
    {
            if (f[x] > y)
            {
                    q.push(P(f[x] = y, x));
            }
    }
    int main()
    {
            //freopen("input.txt", "r", stdin);
            //freopen("output.txt", "w", stdout);
            scanf("%d%d%d", &n, &m, &st);
            while (m--)
            {
                    scanf("%s", op);
                    int o = op[0];
                    scanf("%d%d%d%d", &a[o], &b[o], &c[o], &d[o]);
                    for (i = 0; i < c[o]; i++) //!!!i为到达时间即 到某k点的时间%c[k]
                    {
                            w[o][i] = inf;
                            for (j = 0; j < c[o]; j++) //!!!j为等待时间
                            {
                                    w[o][i] = min(w[o][i], (a[o] * (i + j) + b[o]) % c[o] + d[o] + j);   //!!!处理出每种到达时间最优旅行方法
                            }
                    }
            }
            for (i = 1; i <= n; i++)
            {
                    scanf("%s", g[i] + 1);
            }
            for (i = 1; i <= n; i++)
            {
                    f[i] = inf;
            }
            ext(1, st); //!!!!把起点放入迪杰斯特拉优先队列
            while (!q.empty())
            {
                    P t = q.top();
                    q.pop();
                    if (f[t.second] < t.first)
                    {
                            continue;
                    }
                    for (i = 1; i <= n; i++)
                            if (g[t.second][i] != '.')  //!!!有道路的话进行松弛操作
                            {
                                    ext(i, t.first + w[g[t.second][i]][t.first % c[g[t.second][i]]]);//!!!!松弛操作
                            }
            }
            if (f[n] == inf)
            {
                    puts("-1");
            }
            else
            {
                    printf("%d", f[n] - st);
            }
    }
    View Code
  • 相关阅读:
    mislider jQuery响应式圆形图片轮播图特效制作(图片轮播效果二)
    CSS3 animation实现图片轮播效果 自动显示 无需使用js 含代码(图片轮播效果一)
    HTML5 Canvas 学习笔记(canvas绘制线条、矩形、多边形、圆、自定义图像)
    网页右侧悬浮窗制作
    用JavaScript实现选项卡功能
    XML 可扩展的标记性语言
    继承
    原型和原型链
    HTTP 协议类
    DOM 事件
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7617760.html
Copyright © 2020-2023  润新知