其他分享
首页 > 其他分享> > 编号(CQOI2012,BZOJ2665)

编号(CQOI2012,BZOJ2665)

作者:互联网

编号(CQOI2012)

题目大意

你需要给一批商品编号,其中每个编号都是一个7位16进制数(由0~9, a-f组成)。为了防止在人工处理时不小心把编号弄错,要求任意两个编号至少有三个位置对应的数字不相同。第一个编号为0000000,第二个编号为不违反上述规定的前提下最小的编号,…,每次分配一个新编号时,总是选择不和前面编号冲突的最小编号(注意编号都是16进制数,可以比较大小)。按此规律,前面若干编号分别是:0000000, 0000111, 0000222, …, 0000fff, 0001012, 0001103,0001230,0001321,0001456,…

输入k,你的任务是求出第k小的编号。

思路

比较神仙的\(DP\)题。

任意两个数都至少三个位置不同,说明只要存在两个数存在五个位完全相等时,就不合法了。

那么我们直接暴力标记这五个位置,记\(DP[w][a][b][c][d][e]\),\(w\)表示当前的5个数字存在于7个位中的哪5个。\(a,b,c,d,e\)表示五个数的值。那么一共存在状态\(\tbinom{5}{7}\) 21个,所以数组总共开\(21*16^5\).

我们暴力\(16^7\)次枚举每位的数字,如果前面21种状态都为\(false\),便可计入,并将这些状态都标记为\(true\)。

code

#include<bits/stdc++.h>
#define FOR(i,l,r) for(register int i=(l),i##R=(r);i<=i##R;i++)
#define DOR(i,r,l) for(register int i=(r),i##L=(l);i>=i##L;i--)
#define loop(i,n) for(register int i=0,i##R=(n);i<i##R;i++)
#define mms(a,x) memset(a,x,sizeof a)
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
template<typename A,typename B>inline void chkmax(A &x,const B y){if(x<y)x=y;}
template<typename A,typename B>inline void chkmin(A &x,const B y){if(x>y)x=y;}
const int N=(1<<28),M=2e5+5;
int K;
int dp[25][16][16][16][16][16];
void Print(int a[]){
    loop(i,7)
        printf("%c",a[i]>=10?a[i]-10+'a':a[i]+'0');
}
void solve(){
    loop(a,16)loop(b,16)loop(c,16)loop(d,16)loop(e,16)loop(f,16)loop(g,16){
        if(
        !dp[1][a][b][c][d][e]&&
        !dp[2][a][b][c][d][f]&&
        !dp[3][a][b][c][d][g]&&
        !dp[4][a][b][c][e][f]&&
        !dp[5][a][b][c][e][g]&&
        !dp[6][a][b][c][f][g]&&
        !dp[7][a][b][d][e][f]&&
        !dp[8][a][b][d][e][g]&&
        !dp[9][a][b][d][f][g]&&
        !dp[10][a][b][e][f][g]&&
        !dp[11][a][c][d][e][f]&&
        !dp[12][a][c][d][e][g]&&
        !dp[13][a][c][d][f][g]&&
        !dp[14][a][c][e][f][g]&&
        !dp[15][a][d][e][f][g]&&
        !dp[16][b][c][d][e][f]&&
        !dp[17][b][c][d][e][g]&&
        !dp[18][b][c][d][f][g]&&
        !dp[19][b][c][e][f][g]&&
        !dp[20][b][d][e][f][g]&&
        !dp[21][c][d][e][f][g]
        )
        {
            K--;
            if(!K){
                int A[7]={a,b,c,d,e,f,g};
                Print(A);
                return;
            }
            dp[1][a][b][c][d][e]=1;
            dp[2][a][b][c][d][f]=1;
            dp[3][a][b][c][d][g]=1;
            dp[4][a][b][c][e][f]=1;
            dp[5][a][b][c][e][g]=1;
            dp[6][a][b][c][f][g]=1;
            dp[7][a][b][d][e][f]=1;
            dp[8][a][b][d][e][g]=1;
            dp[9][a][b][d][f][g]=1;
            dp[10][a][b][e][f][g]=1;
            dp[11][a][c][d][e][f]=1;
            dp[12][a][c][d][e][g]=1;
            dp[13][a][c][d][f][g]=1;
            dp[14][a][c][e][f][g]=1;
            dp[15][a][d][e][f][g]=1;
            dp[16][b][c][d][e][f]=1;
            dp[17][b][c][d][e][g]=1;
            dp[18][b][c][d][f][g]=1;
            dp[19][b][c][e][f][g]=1;
            dp[20][b][d][e][f][g]=1;
            dp[21][c][d][e][f][g]=1;    
        }
    }
}
int main(){
    scanf("%d",&K);
    solve();
    return 0;
}

标签:21,16,loop,&&,编号,BZOJ2665,dp,CQOI2012
来源: https://www.cnblogs.com/Heinz/p/11443156.html