首页 > 代码库 > POJ 2228 Naptime 环状DP
POJ 2228 Naptime 环状DP
一个环,分成 N 个区间,每个区间有个权值,你可以选择 B 个区间,这些区间可以连续也可以不连续。
那么如何使得选中的区间中的权值之和最大。有个限制条件,被选中的任何连续区间,第一个区间的权值是不算的。
比如你选中编号为 k, k + 1, k + 2 的这 3 个区间时,第编号 k 的区间的权值是不算进去的,
只能算后两个区间 k + 1 和 k + 2 区间的权值之和(但是你损耗了 3 个区间,而不是两个)。
只选择单个区间的时候也是一样,单个区间的权值算作 0。
#include <iostream> #include <cstring> using namespace std; const int inf = 99999999; const int sleep = 1; const int active = 0; long long DP[2][2][3900]; int utilities[3900]; int periods; int can_be_used; void dp_solve(){ for( int period = 2; period <= periods; ++period ){ for( int used = 0; used <= can_be_used; ++used ){ DP[period % 2][active][used] = max( DP[( period - 1 ) % 2][sleep][used], DP[( period - 1 ) % 2][active][used] ); if( used > 0 ) DP[period % 2][sleep][used] = max( DP[( period - 1 ) % 2][sleep][used - 1] + utilities[period], DP[( period - 1 ) % 2][active][used - 1] ); else DP[period % 2][sleep][used] = -inf; } } } int main(){ while( cin >> periods >> can_be_used ){ for( int period = 1; period <= periods; ++period ) cin >> utilities[period]; for( int used = 0; used <= can_be_used; ++used ){ DP[1][sleep][used] = -inf; DP[1][active][used] = -inf; } DP[1][active][0] = 0; DP[1][sleep][1] = 0; dp_solve(); int ans1 = max( DP[periods % 2][sleep][can_be_used], DP[periods % 2][active][can_be_used] ); for( int used = 0; used <= can_be_used; ++used ){ DP[1][sleep][used] = -inf; DP[1][active][used] = -inf; } DP[1][sleep][1] = 0; dp_solve(); int ans2 = max( DP[periods % 2][sleep][can_be_used] + utilities[1], DP[periods % 2][active][can_be_used] ); int ans = max( ans1, ans2 ); cout << ans << endl; } return 0; }
POJ 2228 Naptime 环状DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。