洛谷金秋夏令营模拟赛 第2场 T11737 时之终末

Posted 友人A

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷金秋夏令营模拟赛 第2场 T11737 时之终末相关的知识,希望对你有一定的参考价值。

这道题就是道状压dp...比赛的时候太贪心 然后状压又不好 所以T2 T3一起挂了QAQ 吸取教训QAQ

f[i][j][k]表示前i个数选了j个 最后a个的状态为k的答案

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using std::swap;
const int M=157;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<0||c>9){if(c==-) f=-1; c=getchar();}
    while(c>=0&&c<=9){ans=ans*10+(c-0); c=getchar();}
    return ans*f;
}
int n,m,a,b,k,ly;
int v[M],sz[M];
int f[2][55][70007],y,w[7007],val[70007],ans;
int max(int a,int b){return a>b?a:b;}
void maxs(int&a,int b){if(a<b) a=b;}
int main(){
    n=read(); m=read(); a=read(); b=read();
    for(int i=1;i<=n;i++) v[i]=read();
    for(int i=1;i<=b;i++){
        k=read(); y=read();
        int s=0;
        for(int j=1;j<=k;j++) ly=read(),s|=(1<<(a-ly));
        w[s]+=y;
    }
    int now=0,last=1,tot=1<<a;
    for(int i=0;i<tot;i++) for(int x=i;x;x=(x-1)&i) val[i]+=w[x];
    memset(f[now],-0x3f,sizeof(f[now]));
    for(int s=0;s<tot;s++){
        int x=val[s];
        int sz=0;
        for(int i=0;i<a;i++)if((s>>i)&1) sz++,x+=v[a-i];
        f[now][sz][s]=x;
    } 
    for(int i=a+1;i<=n;i++){
        swap(now,last);
        memset(f[now],-0x3f,sizeof(f[now]));
        for(int j=0;j<=m;j++)
        for(int s=0;s<tot;s++)
        maxs(f[now][j+(s&1)][s],max(f[last][j][s>>1],f[last][j][s>>1|1<<(a-1)])+val[s]+(s&1)*v[i]);
    }
    for(int s=0;s<(1<<a);s++) for(int j=0;j<=m;j++) maxs(ans,f[now][j][s]);
    printf("%d\n",ans);
    return 0;
}
View Code

 

以上是关于洛谷金秋夏令营模拟赛 第2场 T11737 时之终末的主要内容,如果未能解决你的问题,请参考以下文章

[周记]8.7~8.16

洛谷 U361 序列操作(NOIP模拟赛T2)

洛谷 U360 子矩阵 (NOIP模拟赛T1)题解

JSOI2018冬令营游记&总结(迁移自洛谷博客)

洛谷普及试炼场之旅

NKOJ 2017信息学夏令营第1场(图论专项练习)