description
表示的各个数位的乘积。
给的矩阵每个矩阵上都有一块金子,一次变化后,金子从变到。
问一次变化后矩阵上金子个数前大的和为多少。
solution
- 首先发现题目最终要的性质,虽然很大,但一共只有至多种。
因为是由多个一位数乘起来,。打个表发现数量为种。
相当于说最后有金子的位置很少。
因此考虑预处理出所有可能的值并离散化(标个号),然后求多少个能得到,设这个方案数为。 - 因为跟数位有关,而且离散化后的状态数很小,考虑数位dp求方案数。
*这里的数位dp是递推(没有写记忆化)而且是从个位往高位推的。
设表示填了后位,乘积为(当然是离散化后的标号),是否大于的后位。(转移见代码)
最后这个在统计答案的时候有用,的情况位数就必须小于了。 - 现在已经求得,最后位置的金子数为。
问题转化为:求的前大。
二维的乘积最大,考虑定下一维,从大到小移动第二维(第一维固定,肯定第二维取还没用过的最大的),用堆维护(堆里面存二元组,按乘积最大排序)
即先将从小到大排序。对于每个,把加入(是最后一个)
每次取出堆顶,把第二维减一,执行次可得到结果。
code:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=15001;
const ll mod=1e9+7;
map<ll,int>mp;
ll n,pm[N];
int m,k;
void init() {
ll w=1;
for(int i=0;i<=39;i++) {
ll x=w;
for(int j=0;j<=25;j++) {
ll y=w;
for(int l=0;l<=17;l++) {
ll z=w;
for(int r=0;r<=14;r++) {
pm[mp[w]=++m]=w;
w*=7;
if(w>n) break;
}
w=z*5;
if(w>n) break;
}
w=y*3;
if(w>n)break;
}
w=x*2;
if(w>n)break;
}
}
ll dp[17][N][2];
int len,a[N];
ll c[N]; //乘积为$i$对应的方案数
void DP() {
ll x=n;
while(x) {a[++len]=x%10;x/=10;}
for(int j=1;j<=9;j++) {dp[1][mp[j]][j>a[1]]=1;}
for(int i=2;i<=len;i++) {
for(int j=1;j<=m;j++) {
ll w=pm[j];
for(int k=1;k<=9;k++) {
if(w%k)continue;
int o=mp[w/k];
if(k<a[i]) {dp[i][j][0]+=dp[i-1][o][0]+dp[i-1][o][1];}
else if(k>a[i]) {dp[i][j][1]+=dp[i-1][o][0]+dp[i-1][o][1];}
else {
dp[i][j][0]+=dp[i-1][o][0];
dp[i][j][1]+=dp[i-1][o][1];
}
}
}
}
for(int i=1;i<=len;i++)for(int j=1;j<=m;j++) {
c[j]+=dp[i][j][0]+((i==len)?0:dp[i][j][1]);
}
}
struct pq {
int x,y;
bool operator <(const pq &u) const{return c[x]*c[y]<c[u.x]*c[u.y];}
};
priority_queue<pq> Q;
void solve() {
k=min((ll)k,(ll)m*m);
sort(c+1,c+1+m);
for(int i=1;i<=m;i++)Q.push((pq){i,m});
ll ans=0;
while(!Q.empty()&&k--) {
int x=Q.top().x,y=Q.top().y; Q.pop();
ans=(ans+c[x]*c[y])%mod;
if(y>1)Q.push((pq){x,y-1});
}
printf("%lld",ans);
}
int main() {
scanf("%lld%d",&n,&k);
init();
DP();
solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
2021-07-13 B - A Simple Task