1310. ACM Diagnostics

http://acm.timus.ru/problem.aspx?space=1&num=1310

题目中说的 “the lexicographically increasing list”

10 和 2  谁更小呢,我刚开始没管这么多,直接按数的大小算的,把 2 放在了 10 的前面

然后也过了,但是题意是不是这个意思?

思路:

数位DP + 二分

代码:

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

	/**
	 * @param args
	 */
	static final int N = 105;
	static final int M = 55;
	static final BigInteger[][][] dp=new BigInteger[N][M][M];
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		for(int i=0;i<N;++i){
			for(int j=0;j<M;++j){
				for(int l=0;l<M;++l){
					dp[i][j][l]=BigInteger.ZERO;
				}
			}
		}
		int n,m,k;
		BigInteger b;
		n=in.nextInt();
		m=in.nextInt();
		k=in.nextInt();
		b=in.nextBigInteger();
		b=b.add(BigInteger.ONE);
		dp[0][1][0]=BigInteger.ONE;
		for(int i=0;i<n;++i){
			for(int l=0;l<k;++l){
				BigInteger tmp=BigInteger.ZERO;
				for(int j=1;j<=m;++j){
					tmp=tmp.add(dp[i][j][l]);
				}
				for(int w=1;w<=m;++w){
					dp[i+1][w][(l+w)%k]=dp[i+1][w][(l+w)%k].add(tmp);
				}
			}
		}
		BigInteger l=BigInteger.ZERO;
		BigInteger r =BigInteger.valueOf(m).pow(n).subtract(BigInteger.ONE);

		while(l.compareTo(r)<=0){
			BigInteger mid=l.add(r).divide(BigInteger.valueOf(2L));
			BigInteger tmp=gnum(mid,n,m,k);
			
			if(tmp.compareTo(b)>=0){
				r=mid.subtract(BigInteger.ONE);
			}
			else{
				l=mid.add(BigInteger.ONE);
			}
		}
		int[] a = new int[n];
		BigInteger M = BigInteger.valueOf((long)(m));
		for(int i=0;i<n;++i){
			a[i]=l.mod(M).intValue()+1;
			l=l.divide(M);
		}
		for(int i=n-1;i>=0;--i){
			System.out.print(a[i]);
			if(i>0)System.out.print(" ");
		}
		System.out.println();
		
	}
	public static BigInteger gnum(BigInteger mid,int n,int m,int mod){
		BigInteger M = BigInteger.valueOf((long)(m));
		int[] a = new int[n];
		for(int i=0;i<a.length;++i){
			a[i]=mid.mod(M).intValue()+1;
			mid=mid.divide(M);
		}
		BigInteger tmp=BigInteger.ZERO;
		int k=0;
		for(int i=n-1;i>=0;--i){
			for(int j=a[i]-1;j>=1;--j){
				tmp=tmp.add(dp[i+1][j][k]);
			}
			if(i==0){
				tmp=tmp.add(dp[i+1][a[i]][k]);
			}
			k=( (k-a[i])%mod+mod)%mod;
		}
		return tmp;
	}

}
原文地址:https://www.cnblogs.com/liulangye/p/3350251.html