zoukankan      html  css  js  c++  java
  • 设置(settings)

    设置(settings)

    题目描述

    如题所示,这将是一个关于设置的问题。

    你需要通过对一个控制台进行设置,来得到不同的效果。

    这个控制台由n个控制元件组成,每个元件有m种设置,其中i号元件的第j种设置将会给整体带来a[i][j]的效果值。

    最终的效果值是所有n个元件所选设置的效果值之和。

    然而,效果值并不是越大或越小越好,不同的效果值有不同的意义。

    所以我们要求你给出效果值最小的那k种不同的方案(2种方案不同,当且仅当2种方案中存在至少1个元件的设置不同)。

    不过由于我们其实并不关心你给出的那k种方案是什么,只需要弄清你是否能够找出那些方案,所以你只需要输出所有k种方案的效果值的异或和。

    输入

    第一行3个正整数n,m,k

    接下来n行,每行m个非负整数,其中第i行第j个数表示第i个控制元件的第j种设置的效果值a[i][j]

    输出

    仅一行一个整数,表示k种方案的效果值的异或和

    样例输入

    3 2 2
    11 21
    9 25
    17 19

    样例输出

    2

    提示

    样例说明

    最小的2种方案的效果值分别为37(11+9+17)和39(11+9+19),异或和为37 xor 39 = 2

    数据规模和约定

    对于30%的数据,m^n<=10^6,k<=30000

    对于另外30%的数据n<=100,n*m<=50000,k<=50000

    对于100%的数据,n*m<=300000,k<=300000,保证m^n>=k,任意一个控制元件的任意一种设置效果值均不超过10^9


    solution
    我们考虑拿n维向量做状态,每一个点拓展出n个,标记判重,拓展出k大即可。
    显然状态数太多了。
    我们考虑减少一个状态的来源,使得每个状态仅被拓展一次。
    那么可以考虑按顺序向后加。
    也就是一个状态拓展到了第i位,那么他的后继状态一定拓展到>=i位
    每一个点拓展出三个后继状态:i加一个块,i+1变成1个块,把1个块的i变成0个,i+1变成1个块
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<queue>
    #define maxn 300005
    #define ll long long
    using namespace std;
    int n,m,k;
    vector<int>a[maxn];
    ll ans;
    struct node{
        int x,num;ll v;
    };
    bool operator <(node a,node b){return a.v>b.v;}
    priority_queue<node>q;
    bool cmp(vector<int> a,vector<int> b){
        return a[1]-a[0]<b[1]-b[0];//////////////////////
    }
    int main(){
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++){
            for(int j=1,t;j<=m;j++){
                scanf("%d",&t);a[i].push_back(t);
            }
            sort(a[i].begin(),a[i].end());
        }
        sort(a+1,a+n+1,cmp);
        ll val=0;
        for(int i=1;i<=n;i++)val+=a[i][0];
        /*
        for(int i=1;i<=n;i++){
        for(int j=0;j<m;j++)cout<<a[i][j]<<' ';cout<<endl;
    }*/
        q.push((node){1,0,val});
        while(k){
            //cout<<"k "<<k<<endl;
            node t=q.top();q.pop();
            k--;ans^=t.v;
            //printf("id=%d num=%d v=%lld
    ",t.x,t.num,t.v);
            if(t.num<m-1)q.push((node){t.x,t.num+1,t.v-a[t.x][t.num]+a[t.x][t.num+1]});
            if(t.num>0&&t.x<n)q.push((node){t.x+1,1,t.v-a[t.x+1][0]+a[t.x+1][1]});
            if(t.num==1&&t.x<n){
                ll nv=t.v+a[t.x][0]-a[t.x][1];
                nv=nv+a[t.x+1][1]-a[t.x+1][0];
                q.push((node){t.x+1,1,nv});
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    P2774 方格取数问题 题解
    golang文档(目录)
    下载安装
    微信小程序canvas画布新接口type为2D时wx.canvasToTempFilePath的参数差异
    【工具】让Mac能读取NTFS格式的移动硬盘
    codeforces 1562 E. Rescue Niwen! (dp)
    UVa1342 That Nice Euler Circuit (计算几何)
    ccpc2021 网络选拔赛 H. GCD on Sequence (线段树)
    codeforces 1558 D. Top-Notch Insertions (线段树+组合)
    codeforces 1561 E. Bottom-Tier Reversals (构造)
  • 原文地址:https://www.cnblogs.com/liankewei/p/10409445.html
Copyright © 2011-2022 走看看