集訓dp基礎題

2022-05-31 16:51:13 字數 3785 閱讀 2656

集訓dp基礎題

poj 3176 cow bowling

給你乙個三角形,從第乙個往下選,每次只能選該數下面的兩個最近的數中的乙個,問能取的數的最大總和。

題解:dp[i] [j] = max(dp[i-1] [j-1], dp[i] [j]) + a[j];(j != 0 && j != i)

dp[i] [0] = dp[i-1] [0] + a[0];

dp[i] [j] = dp[i-1] [j-1] + a[i]; (i == j)

最後列舉dp[n-1] [j] (0 <= j < n)求最大就是了。

#include #include using namespace std;

int main()

}for(int i = 0; i < n; i++)

printf("%d\n", maxn);

}return 0;

}

poj 2229 sumsets

輸入乙個n,把n拆分成2的次方相加,問方案數。

題解:dp[1] = 1;

dp[i] = dp[i-1] + dp[i/2] ;(i 是偶數)

dp[i] = dp[i-1];(i是奇數)

/*

2 = 1+1;

2 = 2;

//顯然3可以直接從2推出,奇數都可以

3 = 1+1+1;

3 = 2+1;

//4的前兩個可以由3直接推出,而後兩個除以2恰好可以由2推出

4 = 1+1+1+1;

4 = 2+1+1;

4 = 2+2;

4 = 4;

*/#include int dp[1000010];

int mod = 1e9;

int main()

while(~scanf("%d", &n))

return 0;

}

有兩棵蘋果樹會掉蘋果,t秒內每秒會在某一棵蘋果樹掉蘋果,但是john很懶,只願意移動至多w次,問他能接到的最多蘋果樹。(剛開始他在1號樹

題解:如果是偶數次移動,那麼他肯定在1號樹,如果是奇數次移動,他就會在2號樹;

dp[i] [j] 第i秒移動j次的最多蘋果數。

#include #include #include using namespace std;

int main()

for(int i = 1; i <= n; i++) }}

printf("%d\n", dp[n][k]);

}return 0;

}

poj 3616 milking time

給出多個開始時間和結束時間及該段時間能擠的牛奶的量,每次工作相隔k小時,比如你4結束工作,那麼最早能在k+4開始新一輪工作,求你能擠的牛奶的量最多是多少。

題解:按結束時間從小到大排序;

dp[i] 表示第i個小時能擠的最多的牛奶的量

dp[i] = max(max(dp[i], dp[i-a[cnt].u] + a[cnt].w), w[i])

#include #include #include using namespace std;

struct node

a[1000010];

int dp[1000010];

bool cmp(node x, node y)

int main()

sort(a, a + m, cmp);

memset(dp, 0, sizeof(dp));

int cnt = 0;

for(int i = 1; i <= n; i++)

}else dp[i] = dp[i-1];

}printf("%d\n", dp[n]);

}return 0;

}

poj 3280 cheapest palindrome

給你乙個字串,通過刪減或者插入一些字母,使得這個字串成為回文字串,每乙個字母都有刪減和插入該字母的體力值a[i]和b[i],求體力值最少

題解:在字串中,插入乙個字母和刪減乙個字母的效果是一樣的,c[i] = min(a[i], b[i]);

dp[i] [j] 表示第i位到第j位最少體力值。

dp[i] [j] = min(dp[i-1] [j] + c[i], dp[i] [j-1] + c[j);(str[i] !+ str[j])

dp[i] [j] = dp[i+1] [j-1];(str[i] == str[j])

#include #include #include #include using namespace std;

const int maxm = 2005;

char ch[2];

int change[27];

char str[maxm];

int dp[maxm][maxm];

int main()

for(int i = m - 1;i >= 0;i--)

}printf("%d\n",dp[0][m - 1]);

return 0;

}

poj 1742 coins

題意:給你n種銀幣,每種硬幣價值為a[i], 有c[i]個,問這些銀幣能組成1-m之間多少個數

題解:看**

#include #include #include using namespace std;

int main()

for(int j = 0; j <= m - a[i]; j++)

}for(int i = 1; i <= m; i++)

printf("%d\n", ans);

}return 0;

}

poj 3046 ant counting

有n個螞蟻,屬於1-t個家族,問從這些螞蟻裡面取出a, a+1...b個螞蟻,一共有多少種取法?

題解:挑戰書68-69頁

狀態轉移方程:dp[i] [j] = dp[i-1] [j] + dp[i] [j-1] - dp[i-1] [j - 1 - a[i - 1]];

#include #include int dp[1010][100010];

int main()

for(int j = 0; j <= t; j++)

for(int j = 1; j <= t; j++)

else }}

for(int i = a; i <= b; i++)

printf("%d\n", ans%1000000);

}return 0;

}

poj 3181 dollar day

題意:有價值為1-m的銀幣,每種銀幣有無數個,問用這些銀幣組成n有多少種?

題解:dp[i] [j] 表示組成價值為i且最大的銀幣的值不超過j的方法

dp[i] [j] = dp[i] [j -1] + dp[i-j] [j];

注意此處需要高精度,下面方法很巧妙

#include #include #include using namespace std;

long long a[1005][105],b[1005][105],inf = 1e18;

int main()

printf("%d\n",dp[n][k]);

return 0;

}

命運(dp基礎題)

穿過幽谷意味著離大魔王lemon已經無限接近了!可誰能想到,yifenfei在斬殺了一些蝦兵蟹將後,卻再次面臨命運大迷宮的考驗,這是魔王lemon設下的又乙個機關。要知道,不論何人,若在迷宮中被困1小時以上,則必死無疑!可憐的yifenfei為了去救mm,義無返顧地跳進了迷宮。讓我們一起幫幫執著的他...

簡單基礎數字 dp 題

終於比較理解了數字 dp qwq 處理大數區間的計數,分成每一位考慮,f 考慮從高到低位在第 pos 位並且滿足某些條件的答案,這個東西我們可以記憶化搜尋,但是注意要設計好狀態,不然會漏或者重複計算某些情況 qwq 需要觀察題目有沒有前導 0 限制,不過這個也不是重點了。關鍵在於對狀態的設計。zjo...

集訓 DP 搜尋 線段樹

集訓contest位址 vj private contest 128411 problem a poj 1018 剛開始非常缺乏思路,後來聽大家的討論再研究一下發現這道題可以暴力列舉a的。需要注意的是 f和 lf的問題。其實這個鍋不能給c g 編譯器,怪就怪當年的c標準委員會。double本來就應該...