题意:长度为n的数列,选择m个不想传递的区间,与所有区间的数字最大。
问题解决:问题中没有说m的范围。 我还以为这个怎么写,后来发现交流代码都是o (纳米)
首先考虑最简单的DP。 d p [ i ] [ j ] dp[i][j] dp[i][j]表示第一个gddbbz个数字被划分为i i i个区间的最大区间之和。 状态转移方程是
第j个个数不是新的区间。 DP [ I ] [ j ]=DP [ I ] [ J1 ] a [ j ] DP [ I ] [ j ]=DP [ I ] [ j1] [ j ]=DP [ I ] [ j1] )
考虑到各只与I1I-1I1和ii有关,可优化转化为一维序列。
外侧循环设定增加,保证和8561i-1 8561的转移无误; 内层循环设定gddbbz增加,从而保证gddbbz和j 1 j-1 j1的转移。
第一个j 1 j-1 j1个最大和用pre[j1]pre[j1]表示。
交流代码: # include cstdio # include iostream # include vector # include string # include queue # include algorithm # include cmath # include include includeiomanip # includecstdlib # include cstring # define rep (I,a,b ) for(intI=) a ); I=(b; I ) #定义lep (I,a,b ) for ) intI=(a ); I=(b; I--#definepiipairint,int#define pll pairlong long,longlong # definempmake _ pair # definepbpush _ back # definefirfiririon x sizeof(a ) # define INF0x 3f 3f 3f # definemultiint; 扫描(' % d ',t ); while(t----usingnamespaceSTD; 泰普德夫龙龙LL; 类型双数据库; const int N=1e6 5; 常数输入模式=10007; 常数数据库EPS=1e-6; constdbpi=ACOS(-1.0; int n,m,s[N]; ll pre[N],dp[N],tmp; int main () ifndef online _ judge freopen (d :workdata.in )、' r '、stdin ); #endifwhile(~scanf ) (%d%d ),m,n ) ) rep ) I,1,n ) ) scanf ) %d ),s[i] ); pre[i]=dp[i]=0; (rep ) I,1,m ) )由于分成//I1块仅涉及I块,因此单空间tmp=-INF; REP(j,I,n ) {DP[j]=max ) DP[j-1],pre[j-1] ) s[j]; pre[j-1]=tmp; //不包含自己的最大前一个tmp=max(tmp,dp[j] ); }printf('%lld(n )、tmp ); }