最近考試總是dp簽到題,本身就是個弱項, 寫個小結
為了簡化問題(名稱)
先宣告「我」是第乙個拿蛋糕的那個人
「我」想要得到最大值
定義\(dp[i][j]\)表示取完區間\(i,j\)我能得到的最大值並且最後一次是我取走的
考慮如何轉移
對答案有貢獻的區間長度為奇數
因為根據定義要保證最後一次是我取的
最後一次我取走了\(a[j]\)
狀態將從\(dp[i][j - 1]\)轉移得到
另乙個人取走了\(a[i]\)或\(a[j-1]\)
判斷邊界可以出**了
#include #include #include #include #define int long long
#define max(a, b) ()
using namespace std;
inline int read()
const int ss = 4004;
int dp[ss][ss], a[ss];
signed main()
} cout << ans << endl;
return 0;
}
在座標系中給出n個點(資訊),以及移動距離的限制
距離表示為曼哈頓距離
問在移動限制內最多能走到多少點(採集多少資訊)
定義\(dp[i][j]\)表示走到第\(i\)個點收集\(j\)個資訊的最小的代價
考慮轉移
\(dp[j][k]\)到\(dp[i][k+1]\)證明從\(j\)走到了\(i\),收集到了第\(k+1\)個資訊
代價為從\(j\)到\(i\)的曼哈頓距離
統計答案
列舉對於每個點能收集\(j\)個資訊
如果走到當前點收集\(j\)個資訊的代價比限制要少
用\(j\)更新答案即可
#include #include #include #include #define max(a, b) ()
#define min(a, b) ()
#define getdis(i, j) (abs(x[i] - x[j]) + abs(y[i] - y[j]))
using namespace std;
inline long long read()
const int ss = 105;
long long dp[105][105];
long long x[ss], y[ss];
signed main()
register long long d = read();
for(register int i = 2; i <= n; i++)
for(register int j = 1; j <= i - 1; j++)
for(register int k = 1; k <= j; k++)
dp[i][k + 1] = min(dp[i][k + 1], dp[j][k] + getdis(i, j));
register long long ans = 0;
for(register int i = 1; i <= n; i++)
for(register int j = 1; j <= i; j++)
printf("%lld\n", ans);
return 0;
}
線性dp 區間dp
1 尼克的任務 額一道挺水的題,愣是做了幾個小時 動態規劃大致的思路還是找乙個轉移 換個詞就是影響 我們可以明顯看出本題的規則 空暇時,一遇到任務必須挑乙個接 求1 n時間內最大空暇時間 所以將任務排序是必要的,兩個關鍵字 再來想象一下當我做到第i 個任務時,我在 st i st i t i 1 時...
切開蛋糕 dp 貪心
出於某些方面的需求,懶羊羊要把一塊n m的蛋糕切成乙個個1 1的小蛋糕。對於一塊蛋糕,我們只能從某條橫線或者某條豎線 要在方格線上 而且這蛋糕是不均勻的,從不同的線切割下去要花不同的代價。而且,對於一塊蛋糕,切割一次以後就被分割成兩塊,而且不能把這兩塊蛋糕拼在一起然後一刀切成四塊,只能兩塊分別再進行...
線狀DP及區間DP
這裡我們都用到動態規劃的思想 dynamic programming,簡稱dp。本質就是組合子問題來求解原問題,且對每個子問題只求解一次。一般來說四個步驟 1.刻畫乙個最優結構特徵 2.遞迴的定義最優解值 3.計算最優解的值 4.利用計算出的資訊構造乙個最優解 這邊直接給出 include incl...