题解,但不是玩具装箱(doge)

陈志轩  •  7个月前


书接上回

首先这是一道橙题对吧

可以简单的证明,若 x 不为0,则每一位都有 9 种选择,答案为 9^N

x 为0,则第一位有 8 种选择,后面 N-1 位有 9 种选择,答案为 8\times 9^{N-1}

特别的,若 N=1 ,则答案为 9

#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
	int x,n,ans = 1;
	cin>>x>>n;
	for (int i = 1;i <= n;i++){
		ans *= 9;
	}
	if (n == 1 || x != 0){
		cout<<ans;
		return 0;
	}
	ans = ans / 9 * 8;
	cout<<ans;
	return 0; 
}

当然,如果你想用数位dp也行(

#include<bits/stdc++.h>
using namespace std;
long long dp[20][20],x,y,z,dgt[20];
long long dfs(long long i,long long o,long long qdl){
	if (!o && dp[i][qdl] != -1){
		return dp[i][qdl];
	}
	if (i == 0){
		return 1;
	}
	long long k = (o?dgt[i]:9),ret = 0;
	for (int d = 0;d <= k;d++){
		if (d == x && x != 0){
			continue;
		}
		if (d == x && x == 0 && qdl){
			continue;
		}
		ret += dfs(i - 1,o && d == k,qdl && (d == 0));
	}
	if (!o){
		dp[i][qdl] = ret;
	}
	return ret;
}

long long calc(long long i){
	memset(dp,-1,sizeof(dp));
	y = 0;
	do{
		y++;
		dgt[y] = i % 10;
	} while (i /= 10);
	return dfs(y,1,1);
}

int main(){
    int n;
    cin>>x>>n;
    if (n == 1){
        cout<<9<<endl;
        return 0;
    }
    cout<<calc((long long)(pow(10,n) - 1)) - calc((long long)(pow(10,n - 1) - 1))<<endl;
    return 0;
}

对了说一下,这题我出的,数位dp是本题std,数学思路来源于@linxuanrui

最后送你们一张图:


Comments: