Misunderstood-Missing-逆向DP
生活随笔
收集整理的這篇文章主要介紹了
Misunderstood-Missing-逆向DP
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Misunderstood … Missing
記憶深刻......打鐵沒做出來的題
題意 :
打怪,有?A?的攻擊力,有?D?的成長,初始均為?0,有?n?輪。
同時有三個數組?a[1:n],b[1:n],c[1:n]
對于每一輪:
首先,攻擊力永久性成長?A=A+D;然后,在下面三個選擇中選擇一種行為:
①、發起進攻,產生?A+ai的傷害。
②、增加成長?D=D+bi。
③、永久性增加攻擊力?A=A+ci。問產生最大總傷害為多少
思路:
逆向DP,DP [ i ]代表的是從第i天到第n天產生的最大傷害,轉移方程分析一下:
如果 這一天選擇 ① 那么 對后面的影響是傷害增加 ai,選擇②對后面影響的是攻擊的那些天數傷害都增加 ( bi * (j-i))
選擇③對后面的影響是,增加傷害為攻擊的天數 * c[ i ],那么dp 需要增加兩個變量 ,一個是方便計算選擇②的情況
增加一個攻擊了的天數下標和,另一個是 當前攻擊的天數數目和,初始值為 dp[ n ] [ 1 ] [ n ] =? a [ n ]?詳見代碼:
#include<bits/stdc++.h> using namespace std; #define maxn 111 #define ll long long ll t,n,a[maxn],b[maxn],c[maxn]; ll dp[3][maxn][maxn*maxn/2],ans; int main() {scanf("%lld",&t);while(t--){ans=0;memset(dp,0,sizeof(dp));scanf("%lld",&n);for(int i=1; i<=n; i++)scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);dp[n&1][1][n]=a[n];for(int i=n-1; i>=1; i--){for(int j=1; j+i<=n; j++){int low = (i+i+j)*(j-1)/2+n;int up = (n+n-(j-1))*j/2;for(int k=low; k<=up; k++){dp[i&1][j+1][k+i]=max(dp[i&1][j+1][k+i],dp[(i+1)&1][j][k]+a[i]);dp[i&1][j][k]=max(dp[i&1][j][k],dp[(i+1)&1][j][k]+(k-j*i)*b[i]);dp[i&1][j][k]=max(dp[i&1][j][k],dp[(i+1)&1][j][k]+j*c[i]);}}}for(int j=1; j<=n; j++)for(int k=n; k<=5050; k++)ans=max(ans,dp[1][j][k]);printf("%lld\n",ans);}return 0; }
?
轉載于:https://www.cnblogs.com/SDUTNING/p/10260406.html
總結
以上是生活随笔為你收集整理的Misunderstood-Missing-逆向DP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 时序数据库InfluxDB
- 下一篇: 端口报错listen eaddrinus