• hdu5798


    官方题解:

    考虑去掉abs符号,发现只有相邻两个数的最高位被影响了才会影响abs的符号,所以可以按照最高位不一样的位置分类,之后考虑朴素枚举x从0到2^20,每次的复杂度是O(400),无法通过,考虑优化,第一种方法是用DFS来进行枚举,第二种则是加入记忆化

    用dfs枚举简单一点

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 typedef long long ll;
     5 int d[20],n,mx,ansx;
     6 ll anss,c[20][20];
     7 void dfs(int i,int x,ll s)
     8 {
     9     if (s>anss) return;
    10     if (i>mx)
    11     {
    12         if (s<anss||(s==anss&&x<ansx))
    13         {
    14             anss=s;
    15             ansx=x;
    16         }
    17         return;
    18     }
    19     for (d[i]=0; d[i]<=1; d[i]++)
    20     {
    21         ll ns=s+c[i][i];
    22         for (int j=0; j<i; j++)
    23             if (d[i]^d[j]) ns-=c[i][j];
    24             else ns+=c[i][j];
    25         dfs(i+1,x+d[i]*(1<<i),ns);
    26     }
    27 }
    28 
    29 int work(int a,int b,int h)
    30 {
    31     if (a<b) swap(a,b);
    32     for (int i=h; i>=0; i--)
    33         c[h][i]+=((a>>i&1)-(b>>i&1))<<i;
    34 }
    35 
    36 int main()
    37 {
    38     int cas;
    39     scanf("%d",&cas);
    40     while (cas--)
    41     {
    42         scanf("%d",&n);
    43         int a,b;
    44         scanf("%d",&a);
    45         memset(c,0,sizeof(c));
    46         mx=19;
    47         for (int i=1; i<n; i++)
    48         {
    49             scanf("%d",&b);
    50             int h=19;
    51             while (h>=0&&!((a>>h&1)^(b>>h&1))) h--;
    52             work(a,b,h);
    53             a=b;
    54         }
    55         while (mx>=0&&!c[mx][mx]) mx--;
    56         anss=1e18; ansx=0;
    57         dfs(0,0,0);
    58         printf("%d %lld
    ",ansx,anss);
    59     }
    60 }
    View Code
    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    int d[20],n,mx,ansx;
    ll anss,c[20][20];
    void dfs(int i,int x,ll s)
    {
        if (s>anss) return;
        if (i>mx)
        {
            if (s<anss||(s==anss&&x<ansx))
            {
                anss=s;
                ansx=x;
            }
            return;
        }
        for (d[i]=0; d[i]<=1; d[i]++)
        {
            ll ns=s+c[i][i];
            for (int j=0; j<i; j++)
                if (d[i]^d[j]) ns-=c[i][j];
                else ns+=c[i][j];
            dfs(i+1,x+d[i]*(1<<i),ns);
        }
    }
    
    int work(int a,int b,int h)
    {
        if (a<b) swap(a,b);
        for (int i=h; i>=0; i--)
            c[h][i]+=((a>>i&1)-(b>>i&1))<<i;
    }
    
    int main()
    {
        int cas;
        scanf("%d",&cas);
        while (cas--)
        {
            scanf("%d",&n);
            int a,b;
            scanf("%d",&a);
            memset(c,0,sizeof(c));
            mx=19;
            for (int i=1; i<n; i++)
            {
                scanf("%d",&b);
                int h=19;
                while (h>=0&&!((a>>h&1)^(b>>h&1))) h--;
                work(a,b,h);
                a=b;
            }
            while (mx>=0&&!c[mx][mx]) mx--;
            anss=1e18; ansx=0;
            dfs(0,0,0);
            printf("%d %lld
    ",ansx,anss);
        }
    }
  • 相关阅读:
    321list,元组,range**数字是不可迭代的!
    320作业
    320基础数据类型初始
    319作业
    316作业
    319 Python基础之格式化输出、逻辑运算符、编码、in not in、while else、
    windows查看端口占用指令
    2016年学习计划
    刷算法的时候有没有必要自写测试用例?
    我们为什么不能只用O记号来谈论算法?
  • 原文地址:https://www.cnblogs.com/phile/p/6399475.html
Copyright © 2020-2023  润新知