『8.25 模拟赛』外卖 (atcoder 100e)

Posted fang-hao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『8.25 模拟赛』外卖 (atcoder 100e)相关的知识,希望对你有一定的参考价值。

题目链接

题目描述

众所周知,(cky)喜欢点外卖。

已知可选的商品有(n)种,(cky)由于胃容量问题只能点两份(不能一种点两份)。(cky)要在防止营养过剩的情况下选择美味度最高的搭配。

具体的,对于每第(i)个商品,(i)正好是其营养成分,(s_i)表示其美味度(商品从(0)开始编号)。

对于每种搭配((a,b)),其营养程度为((a|b)其中(|)表示二进制下的按位或),其美味度为(s_a+s_b)

(cky)要选择满足(a|bleq k)中,(s_a+s_b)最大的((a,b))

由于(cky)好久没去体检,所以不知道能接受多少营养成分,所以希望对于每一种(k)都求出答案。

为了送分,(n)均可以表示为(2^N),其中(N)为整数。



解题思路

首先,因为是或运算,所以我们可以想到高维前缀和。

我们分别维护对于每一个k的最大值和次大值,那么我们就可以利用高维前缀和的方法进行转移。

我们假设dp[ i ][ 0 / 1 ]表示当前数值i的最大值在原序列中的位置(0),和次大值的位置(1),那么我们就可以枚举给i在二进制下的所有为0的位置选择一个加1,这样就可以转移到一个新的状态tmp,(tmp=i+(1<<j))这样就可以由i推到tmp,我么只要比较i和tmp的最大值和次大值,以下有三种情况:

1)tmp的最大值小于i的最大值:那么我们显然是要把tmp的次大值变成tmp的最大值,把i的最大值变成tmp的最大值。

2)tmp的次大值小于i的最大值并且tmp的最大值和i的最大值取的不是同一个位置:那么tmp的次大值变成i的最大值。

2)tmp的次大值小于i的次大值:那么把tmp的次大值改成i的次大值




代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=(1<<21);
int n;
int a[maxn],dp[maxn][2];
int main(){
    scanf("%d",&n);
    for(register int i=0;i<(1<<n);i++){
        scanf("%d",&a[i]);
        dp[i][0]=i;
    }
    for(register int i=0;i<(1<<n);i++){
        for(register int j=0;i+(1<<j)<=(1<<n);j++){
            if(!(i&(1<<j))){
                int tmp=i|(1<<j);
                if(a[dp[tmp][0]]<a[dp[i][0]]){
                    dp[tmp][1]=dp[tmp][0];
                    dp[tmp][0]=dp[i][0];
                }
                else if(a[dp[tmp][1]]<a[dp[i][0]]&&dp[tmp][0]!=dp[i][0]){
                    dp[tmp][1]=dp[i][0];
                }
                else if(a[dp[tmp][1]]<a[dp[i][1]]){
                    dp[tmp][1]=dp[i][1];
                }
            }
        }
    }
    int ans=0;
    for(register int i=1;i<(1<<n);i++){
        ans=max(ans,a[dp[i][0]]+a[dp[i][1]]);
        printf("%d
",ans);
    }
}





以上是关于『8.25 模拟赛』外卖 (atcoder 100e)的主要内容,如果未能解决你的问题,请参考以下文章

11.7模拟赛总结

9.23 NOIP模拟赛总结

模拟AtCoDeer and Rock-Paper

Atcoder Beginner Contest153F(模拟)

AtCoder ARC 100

赛时总结 ◇赛时·II◇ AtCoder ABC-100