题目大意:
解题思路:
如果没有
k
+
1
∣
∑
w
k+1|\sum w
k+1∣∑w 的限制的话就是个简单的 dp
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
+
1
]
[
j
−
1
]
,
d
p
[
i
+
1
]
[
j
+
1
]
)
dp[i][j] = max(dp[i+1][j-1],dp[i+1][j+1])
dp[i][j]=max(dp[i+1][j−1],dp[i+1][j+1])
但是有了倍数限定那么我们要再加一个维度去限定,因为不能这么直接求最大值
那么我们可以这样因为
n
,
m
∈
[
0
,
100
]
,
G
[
i
]
[
j
]
∈
[
0
,
9
]
n,m\in[0,100],G[i][j]\in[0,9]
n,m∈[0,100],G[i][j]∈[0,9]总和最多才
9
×
n
9\times n
9×n
所以还可以再撑开一维度
d
p
[
i
]
[
j
]
[
k
]
表
示
到
了
第
i
行
第
j
列
的
时
候
豆
子
数
量
为
k
是
否
收
集
的
到
dp[i][j][k]表示到了第i行第j列的时候豆子数量为k是否收集的到
dp[i][j][k]表示到了第i行第j列的时候豆子数量为k是否收集的到
k
∈
[
0
,
9
×
n
]
,
i
,
j
∈
[
1
,
m
a
x
(
n
,
m
)
]
k\in[0,9\times n],i,j\in[1,max(n,m)]
k∈[0,9×n],i,j∈[1,max(n,m)]
时间复杂度才
O
(
n
×
m
×
n
×
9
)
O(n\times m\times n\times9)
O(n×m×n×9)
有了dp方程转移就很明显了
AC代码:
#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 1e9 + 9;
const int maxn = 500010;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x) {
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args) {
read(first);
read(args...);
}
const int siz = 105;
bool dp[siz][siz][siz*9];
char path[siz][siz][siz*9];
int n, m, K;
char G[siz][siz];
void slove(int i, int j, int siz) {
string s = "";
cout << siz << "\n";
while(path[i][j][siz] != '\0') {
s.push_back(path[i][j][siz]);
if(path[i][j][siz] == 'R') {
siz -= G[i][j] - '0';
i ++;
j --;
} else {
siz -= G[i][j] - '0';
i ++;
j ++;
}
}
cout << j << "\n";
reverse(s.begin(),s.end());
cout << s;
}
int main() {
IOS;
cin >> n >> m >> K;
for(int i = 1; i <= n; ++ i) cin >> (G[i] + 1);
for(int i = 1; i <= m; ++ i) dp[n][i][G[n][i]-'0'] = 1;
//自最后一行向上更新dp方程
for(int j = n - 1; j >= 1; -- j)
for(int k = 1; k <= m; ++ k)
for(int i = G[j][k]-'0'; i <= 9 * n; ++ i) {
if(dp[j+1][k-1][i-G[j][k]+'0']) {
path[j][k][i] = 'R';
dp[j][k][i] = 1;
}
if(dp[j+1][k+1][i-G[j][k]+'0']) {
path[j][k][i] = 'L';
dp[j][k][i] = 1;
}
}
for(int j = 9 * n; j >= 0; -- j)
for(int i = 1; i <= m && j % (K + 1) == 0; ++ i)
if(dp[1][i][j]) {
slove(1,i,j);
return 0;
}
cout << "-1";
return 0;
}