题解:CF1866D Digital Wallet

一:思路

求最大值,可以考虑dp,结果发现每次考虑时,只需考虑一个 n 行 k 列的矩阵,在这之间选数,所以维护这样一个矩阵来 dp 即可。

同时创建x和y两个数组;

x[n * i+j]:数组中第 i 行第 j 列为止的最大答案。

y[n * i+j]:数组中选上第 i 行第 j 列的最大答案。

然后输出x[n * k];

代码:

#include
#define ll long long
using namespace std;
const int N=20,M=1e5+5;
ll a[M*N],x[105],y[105];
ll n,m,k;
int main(){
	scanf("%lld%lld%lld",&n,&m,&k);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%lld",&a[n*j+i]);
		}
	}
	for(int i=1;i<=m-k+1;i++){
		for(int j=1;j<=n*k;j++){
			y[j]=x[min(j+n-1,n*k)]+a[j+n*i];
		}
		for(int j=1;j<=n*k;j++){
			x[j]=y[j];
		}
		for(int j=2;j<=n*k;j++){
			x[j]=max(x[j],x[j-1]);
		}
	}
	printf("%lld",x[n*k]);
}
/*
3 3 1
10 4 2
8 1 9
4 8 2
*/

你可能感兴趣的:(CF,算法,c++,动态规划,数据结构)