zoukankan      html  css  js  c++  java
  • [CF193B] Xor(暴力,剪枝,异或)

    题目链接:http://codeforces.com/contest/193/problem/B

    题意:一个数列有两种操作,问操作u次后最大是权值和是多少。

    操作1:ai ^ bi

    操作2:ai = api + r

    这题爆搜会TLE,但是有一个很明显的剪枝就是同时异或的话值是一样的。所以用一个pre记录上一步是不是异或。

    仅仅这样会wa,因为事实上的确会存在有两次连续异或,并且最终更新到u的情况。那么需要在剩余操作次数为偶数次的时候都要更新答案,因为要考虑异或成对出现的情况。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 const int maxn = 333;
     6 int n, u, r;
     7 LL a[maxn], b[maxn], k[maxn], p[maxn];
     8 LL ret;
     9 vector<int> path;
    10 
    11 void dfs(int cnt, bool pre) {
    12     if(cnt == u + 1) return;
    13     if((u - cnt) % 2 == 0) {
    14         LL tmp = 0;
    15         for(int i = 1; i <= n; i++) tmp += a[i] * k[i];
    16         ret = max(ret, tmp);
    17     }
    18 
    19     if(!pre) {
    20         for(int i = 1; i <= n; i++) a[i] ^= b[i];
    21         dfs(cnt+1, 1);
    22         for(int i = 1; i <= n; i++) a[i] ^= b[i];
    23     }
    24 
    25     LL t[maxn];
    26     for(int i = 1; i <= n; i++) t[i] = a[i];
    27     for(int i = 1; i <= n; i++) a[i] = t[p[i]] + r;
    28     dfs(cnt+1, 0);
    29     for(int i = 1; i <= n; i++) a[i] = t[i];
    30 }
    31 
    32 int main() {
    33     // freopen("in", "r", stdin);
    34     while(~scanf("%d%d%d",&n,&u,&r)) {
    35         for(int i = 1; i <= n; i++) scanf("%I64d",&a[i]);
    36         for(int i = 1; i <= n; i++) scanf("%I64d",&b[i]);
    37         for(int i = 1; i <= n; i++) scanf("%I64d",&k[i]);
    38         for(int i = 1; i <= n; i++) scanf("%I64d",&p[i]);
    39         ret = -1e18; path.clear();
    40         dfs(0, 0);
    41         printf("%I64d
    ", ret);
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    学习淘宝指数有感
    STL学习小结
    Java里泛型有什么作用
    android 内存泄漏分析技巧
    学道1.3
    严苛模式(StrictMode)
    年龄大了还能够学习编程吗
    ORACLE EXP命令
    数学之路-python计算实战(13)-机器视觉-图像增强
    《C语言编写 学生成绩管理系统》
  • 原文地址:https://www.cnblogs.com/kirai/p/6832731.html
Copyright © 2011-2022 走看看