一條直線上的n個點,其中第i個點位於數軸上的位置x[i]。如果從i跳到j,首先要花費時間|x[j]-x[i]|。 假如i小於j,還需額外花費時間d[i]+a[j],如果i>j,需額外花費時間c[i]+b[j]。已經到過的點無法再次到達。每次可以選擇若干個沒有到過的點,然後在其中乙個點開始,按某種順序跳過所有點,最終跳回開始的點。經過若干次這樣的行動後,最多能消耗多少時間。(一次行動到下一次之間不會消耗時間)
n,m<=5000,a[i],b[i],c[i],d[i]<=1e9
時間限制2s
空間限制256m
其實每乙個點都可以根據四種不同的連邊情況把收益單獨拆分出來,然後用dp解決問題。
f[i][j][k]表示選了前i個點後,有j個出度,k個入度沒有確定。這些不確定的度都是又前i個點與後n-i個點之間的邊產生的。經過觀察後可發現,j、k是同時±1的,所以可以把f[i][j][k]變為f[i][j];
狀態轉移方程如下:
1、f[i+1][j-1]=max(f[i+1][j-1],f[i][j]+x[i+1]+x[i+1]+a[i+1]+c[i+1]);
2、f[i+1][j]=max(f[i+1][j],f[i][j]+a[i+1]+d[i+1]);
3、f[i+1][j]=max(f[i+1][j],f[i][j]+b[i+1]+c[i+1]);
4、f[i+1][j+1]=max(f[i+1][j+1],f[i][j]-x[i+1]-x[i+1]+d[i+1]+b[i+1]);
前三條的轉移條件是j>0。
**如下
#include
#include
#include
#define maxn 5006
#define fr(i,a,b) for(i=a;i<=b;i++)
using
namespace
std;
typedef
long
long ll;
int i,j,n,x[maxn],a[maxn],b[maxn],c[maxn],d[maxn];
ll f[maxn][maxn];
int main()
}f[i+1][j+1]=max(f[i+1][j+1],f[i][j]-x[i+1]-x[i+1]+d[i+1]+b[i+1]);
}printf("%lld\n",f[n][0]);
return
0;}
挖坑記 JZOJ 4727 挺進
一棵樹,求出隨機斷一條邊後,兩個聯通塊直徑和的最大值。n 100000,邊長 100000 時間限制 1s 空間限制 256m 對於樹上每乙個點,預處理出以下資料 1 每棵子樹的根節點到葉節點的最大值 次大值和第三大值d1,d2,d3 2 每棵子樹內直徑長度f 3 每棵子樹的子結點中f son 的最...
挖坑記 JZOJ 4738 神在夏至祭降下了神諭
乙個長度為n的01序列要分段,每一段的0 1個數不能相差k以上,問有多少種分段方案。n 1e5,k n 時間限制 1s 空間限制 256m n 2的dp很容易得出來,在此基礎上優化。b i 表示前1 i個數中0 1個數差,則f i sigma f j b j b i k 建一棵線段樹,表示b i 這...
linux上安裝和使用ffmpeg 挖坑記
小結此處照著網上教程坑略多,務必看完再動手。sudo configure enable shared prefix usr local ffmpeg如果提示yasm版本太舊則安裝一下 sudo apt get install yasm然後再次執行上面的命令即可 ps 這裡僅簡單安裝,configur...