集訓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本來就應該...