时间复杂度 O(nmp) ,明显应该超时。 但是 AC 了。
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
#define lst(x) (x==1?n:x-1)
#define nex(x) (x==n?1:x+1)
int n,m,p,b[N][N],v[N],s[N][N],dp[N];
bool vis[N];
//i点在j时刻的和. s[i][j]
int calc(int i, int j, int k) {
//在点i. 从j时刻开始. 走k步. 多少.
int f=(i+k-1)%n;
if(f==0)f=n;
return s[f][j+k-1]-s[lst(i)][j-1];
}
int f(int i) {
if(vis[i])return dp[i];
if(i==m+1)return 0;
//第i时刻
int ans=f(i+1)-v[1]+calc(1,i,1);
for(int j=1;j<=n;j++) {
for(int k=1;k<=p&&i+k<=m+1;k++) {
//在j买. 走k步
ans=max(ans, f(i+k)-v[j]+calc(j, i, k));
}
}
vis[i]=1,dp[i]=ans;
return ans;
}
int main() {
cin>>n>>m>>p;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
cin>>b[i][j];
}
}
for(int i=1;i<=n;i++) {
cin>>v[i];
}
for(int j=0;j<=m;j++) {
for(int i=1;i<=n;i++) {
if(j==0)s[i][j]=0;
else if(j==1)s[i][j]=b[i][j];
else {
s[i][j]=s[lst(i)][j-1]+b[i][j];
}
}
}
cout<<f(1);
// cout<<calc(2,1,1);
return 0;
}