[HDU 6157]The Karting(DP)
[HDU 6157]The Karting
description
solution
先用前綴和求出di:1→id_i:1\rightarrow idi?:1→i 的距離
前綴和滿足:若在iii點進行方向改變,則iii產生的貢獻是一定的,可以先累計貢獻
也就是說真正的路徑怎么走,我們是不關心的,只關心在哪些點進行了轉向操作
設fi,j,k:f_{i,j,k}:fi,j,k?: 前iii個點選了jjj個特別點left→rightleft\rightarrow rightleft→right比right→leftright\rightarrow leftright→left轉向多kkk個
-
iii點不是特別點
fi?1,j,k→fi,j,kf_{i-1,j,k}\rightarrow f_{i,j,k}fi?1,j,k?→fi,j,k?
-
iii點是特別點,但iii處不轉向
fi?1,j?1,k→fi,j,kf_{i-1,j-1,k}\rightarrow f_{i,j,k}fi?1,j?1,k?→fi,j,k?
-
iii點left→rightleft\rightarrow rightleft→right轉向
fi?1,j?1,k?1+D?2?di→fi,j,kf_{i-1,j-1,k-1}+D-2·d_i \rightarrow f_{i,j,k}fi?1,j?1,k?1?+D?2?di?→fi,j,k?
-
iii點right→leftright\rightarrow leftright→left轉向
fi?1,j?1,k+1+D+2?di→fi,j,kf_{i-1,j-1,k+1}+D+2·d_i\rightarrow f_{i,j,k}fi?1,j?1,k+1?+D+2?di?→fi,j,k?
答案即為fn,m,0f_{n,m,0}fn,m,0?
最后一定是個環,兩種類型的轉向次數一定是相同的
因為did_idi?是前綴和,根據dpdpdp的設定,顯然多的轉向類型產生的貢獻是?-?,靠另一種轉向進行抵消
code
#include <cstdio> #include <iostream> using namespace std; #define maxn 105 #define inf 0x3f3f3f3f int n, m, D; int d[maxn]; int f[maxn][maxn][maxn];int main() {while( ~ scanf( "%d %d", &n, &m ) ) {scanf( "%d", &D );d[1] = 0;for( int i = 2;i <= n;i ++ ) {scanf( "%d", &d[i] );d[i] += d[i - 1];}for( int i = 0;i <= n;i ++ )for( int j = 0;j <= m;j ++ )for( int k = 0;k <= m;k ++ )f[i][j][k] = -inf;f[0][0][0] = 0;//f(i,j,k):前i個數選了j個標記點且從左到右轉向個數比從右到左轉向個數多k個的最大收益 for( int i = 1;i <= n;i ++ ) {f[i][0][0] = 0;for( int j = 1;j <= min( i, m );j ++ ) {for( int k = 0;k <= j;k ++ )f[i][j][k] = max( f[i - 1][j][k], f[i - 1][j - 1][k] );//不轉向i距離就會該方向上的更遠點的d算進去 所以不再加d[i] for( int k = 0;k < j;k ++ )f[i][j][k] = max( f[i][j][k], f[i - 1][j - 1][k + 1] + D + ( d[i] << 1 ) );for( int k = 1;k <= j;k ++ )f[i][j][k] = max( f[i][j][k], f[i - 1][j - 1][k - 1] + D - ( d[i] << 1 ) );}}printf( "%d\n", f[n][m][0] );}return 0; }總結
以上是生活随笔為你收集整理的[HDU 6157]The Karting(DP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [APIO2013]机器人(DP+SPF
- 下一篇: [LOJ 6042]「雅礼集训 2017