专栏文章
题解:P5307 [COCI 2018/2019 #6] Mobitel
P5307题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mio2jqz5
- 此快照首次捕获于
- 2025/12/02 12:19 3 个月前
- 此快照最后确认于
- 2025/12/02 12:19 3 个月前
七夕节到了没人一起过,只能录一个不错的 trick 了。
显然有一个三维的 表示当前在 路径乘积为 的方案数。考虑优化其状态,类似数论分块地,我们将第三维变成至少乘上 才能大于等于 的方案数,这样的 是 级别的。
直接 dp 即可,时间复杂度 。
代码:
CPP#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
bool mbs;
const int mod=1e9+7;
const int maxn=320;
const int maxm=3e3+20;
const int maxk=1e6+20;
#define ll long long
int n,m,a[maxn][maxn],k,dp[2][maxn][maxm],rec[maxm],idx,id[maxk];
#define qx(x,y) id[((x)/(y)+((x)%(y)!=0))]
bool mbt;
int main(){
// cerr<<(&mbs-&mbt)/1024.0/1024.0<<endl;
n=read(),m=read(),k=read();
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read();
for(int i=1;i<=k;i++) rec[++idx]=(k/i+(k%i!=0));
sort(rec+1,rec+1+idx);
idx=unique(rec+1,rec+1+idx)-rec-1;
for(int i=1;i<=idx;i++) id[rec[i]]=i;
for(int i=1;i<=n;i++){
int cur=(i&1);
for(int j=1;j<=m;j++){
for(int c=1;c<=idx;c++) dp[cur][j][c]=0;
if(i==1&&j==1){dp[cur][j][qx(k,a[i][j])]=1;continue;}
if(i!=1)
for(int c=1;c<=idx;c++) dp[cur][j][qx(rec[c],a[i][j])]=(dp[cur][j][qx(rec[c],a[i][j])]+dp[cur^1][j][c])%mod;
if(j!=1)
for(int c=1;c<=idx;c++) dp[cur][j][qx(rec[c],a[i][j])]=(dp[cur][j][qx(rec[c],a[i][j])]+dp[cur][j-1][c])%mod;
}
}
printf("%d\n",dp[n&1][m][1]);
return 0;
}
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...