1. 程式人生 > ><gym101673G. A Question of Ingestion> (DP)

<gym101673G. A Question of Ingestion> (DP)

什麽 pen mem 表示 AC AI eof gym urn

題意:有最多100天 每天有一個食物量 你一開始有一個最大胃口表示你最開始能吃多少食物

   如果你昨天吃了 那麽今天的胃口為昨天的2/3 如果你前天吃了 昨天沒吃 那麽你的胃口可以恢復到前天的情況

   如果你有連續兩天沒吃了 那麽你就可以恢復到最大胃口了 問怎樣安排使一共吃到的食物最多

題解:就裸裸的DP了,反正從沒出過DP(的DP選手

   dp[i][j][k]表示第i天結束後 當前的胃口能級為j 這一天進行的操作k k為0表示今天吃了 k為1表示今天沒吃

   那麽轉移也沒什麽難的了 轉移模擬這幾種狀態即可

   今天吃由昨天轉移來的

   dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - 1][0] + 今天吃);
dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j][0]); 今天不吃

   今天吃由前天轉移來的 dp[i][j][0] = max(dp[i][j][0], dp[i - 2][j][0] + 今天吃]));

   還要處理一下由大前天轉移過來的 這時候你今天吃 能級就為1 今天不吃能級就為0

   反正就xjb搞吧... 我和銅牌題打起來了

技術分享圖片
#include <bits/stdc++.h>
using namespace std;

int q[105];
int e[105];
int dp[105][105][5];

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    memset(dp, 
0, sizeof(dp)); for(int i = 1; i <= n; i++) scanf("%d", &q[i]); e[1] = m; for(int i = 2; i <= n; i++) e[i] = e[i - 1] * 2 / 3; for(int i = 1; i <= n; i++) { dp[i][1][0] = min(q[i], e[1]); if(i > 2) { for(int j = 0; j <= i - 3; j++) { dp[i][
1][0] = max(dp[i][1][0], dp[i - 3][j][0] + min(q[i], e[1])); dp[i][1][0] = max(dp[i][1][0], dp[i - 3][j][1] + min(q[i], e[1])); } } if(i > 1) { for(int j = 0; j <= i - 2; j++) { dp[i][0][1] = max(dp[i][0][1], dp[i - 2][j][0]); dp[i][0][1] = max(dp[i][0][1], dp[i - 2][j][1]); } } for(int j = 1; j <= i; j++) { dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - 1][0] + min(q[i], e[j])); dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j][0]); if(i > 1) dp[i][j][0] = max(dp[i][j][0], dp[i - 2][j][0] + min(q[i], e[j])); } } int ans = 0; for(int i = 1; i <= n; i++) { for(int j = 0; j <= i; j++) for(int k = 0; k < 2; k++) ans = max(ans, dp[i][j][k]); } printf("%d\n", ans); return 0; } /* 8 900 900 600 40 400 20 266 10 177 */
View Code

<gym101673G. A Question of Ingestion> (DP)