• 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
  • 相关阅读:
    java的构造方法 java程序员
    No result defined for action cxd.action.QueryAction and result success java程序员
    大学毕业后拉开差距的真正原因 java程序员
    hibernate的回滚 java程序员
    验证码 getOutputStream() has already been called for this response异常的原因和解决方法 java程序员
    浅谈ssh(struts,spring,hibernate三大框架)整合的意义及其精髓 java程序员
    你平静的生活或许会在某个不可预见的时刻被彻底打碎 java程序员
    Spring配置文件中使用ref local与ref bean的区别. 在ApplicationResources.properties文件中,使用<ref bean>与<ref local>方法如下 java程序员
    poj1416Shredding Company
    poj1905Expanding Rods
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7617760.html
Copyright © 2020-2023  润新知