求调试:
样例(3,3)座标应输出5,实际输出2
0 0 0
0 1 5
1 3 2
方法是dp , dp[i][j][k] (i,j)表示坐标,k表示花了多少钱,转移是枚举除本身以外的可以到达它的所有点(就是它左边和上面的点),orz
#include <bits/stdc++.h>
#define Lon long long
using namespace std;
const int INF=0x7fffffff;
const int N=45+10;
const int K=90+10;
const Lon MOD=998244353;
inline int read()
{
int ret=0;
char c=getchar();
while (c<'0' || c>'9') c=getchar();
while (c>='0' && c<='9')
{
ret=ret*10+c-'0';
c=getchar();
}
return ret;
}
int n,m,k,a[N][N],b[N][N];
Lon dp[N][N][K],val[N][N];
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>b[i][j];
}
}
for(int i=0;i<n;i++) val[i][0] = 1;
for(int i=0;i<m;i++) val[0][i] = 1;
for(int i=1;i<n;i++){
for(int j=1;j<m;j++){
val[i][j] = (val[i-1][j] + val[i][j-1]) % MOD;
}
}
dp[1][1][0] = 1;//向下是a,向右是b
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
//可以购买多张票:转移来源变多
for(int ii=1;ii<=i;ii++){
for(int jj=1;jj<=j;jj++){
if(ii == i && j == jj) continue;//没有考虑路线
int tmp = (i - ii) * a[ii][jj] + (j - jj) * b[ii][jj];//转移的代价
for(int kk=tmp;kk<=k;kk++){
dp[i][j][kk] += (dp[ii][jj][kk - tmp] * val[i - ii][j - jj]) % MOD;
dp[i][j][kk] %= MOD;
}
}
}
}//congmingrenyouxi
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<dp[i][j][k]<<" ";
}
cout<< "\n";
}
return 0;
}
/*
求调试:
样例(3,3)座标应输出5,实际输出2
0 0 0
0 1 5
1 3 2
*/