cf958 C2. Encryption (medium)(dp)
作者:互联网
题意:
把长为n的数组切成k段,每段的得分为段中的数之和模p。问总分最大是多少(总分不用模p)
n <= 2e4,k <= 50,p <= 100
思路:
先考虑朴素dp。\(f(i,k)\) 表示把第 \(1\sim i\) 个数切成 \(k\) 段的最大答案,则 \(f(i,k) = max _{j<i} \{ f(j,k-1) + s[i]-s[j] \}\),其中 \(s[]\) 为前缀和取模。复杂度 \(O(n^2k)\) ,会超时。
优化:注意到p很小,\(f(s[i],k)=max _{0\le s' < p} \{f(s',k-1) + s[i]-s' \}\)
memset(f, 0xcf, sizeof f), f[0][0] = 0;
for(int i = 1; i <= n; i++)
for(int ss = 0; ss < p; ss++)
for(int k = 1; k <= K; k++)
f[s[i]][k] = max(f[s[i]][k], f[ss][k-1] + (s[i] - ss + p) % p);
cout << f[s[n]][K];
标签:medium,题意,切成,max,总分,C2,dp,长为 来源: https://www.cnblogs.com/wushansinger/p/15754194.html