Article directory
Topic link: Baoyan Exercise Series
A - Max Sum Plus Plus
Topic link: A - Max Sum Plus Plus
Reference blog: Max Sum Plus Plus (Maximum of Dynamic Programming+m Subsection Sum)
- Train of thought:
- State construction: dp[i][j] denotes the maximum sum of the first j numbers divided into I groups (the jth number must be in the group).
- max(dp[m][j])
- Dynamic transfer equation: DP [i] [j] = max (dp [i] [j-1] + a [j], Max (dp [i-1] [k] + a [j]) (0 < K < j).
dp[i][j-1]+a[j] denotes that the first J-1 is divided into group i, and the first j must be placed in the previous group.
The former (0 < K < j) represented by Max (dp [i-1] [k]) + a [j]) was divided into i-1 group, and the jth group was separately divided into a group.
Code:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int MAX = 1000005; int dp[MAX], a[MAX]; int Max[MAX]; int main() { int n, m; while(cin >> m >> n) { for(int i=1; i<=n; i++) cin >> a[i]; memset(dp, 0, sizeof(dp)); memset(Max, 0, sizeof(Max)); int mmax;//Represents the current maximum for(int i=1; i<=m; i++) { mmax = -1<<29; for(int j=i; j<=n; j++) { dp[j] = max(dp[j-1]+a[j], Max[j-1]+a[j]); Max[j-1] = mmax;//Updated for the next I loop, representing max(dp[i-1][k]) mmax = max(mmax, dp[j]);//Keep ahead } } cout << mmax << endl; } return 0; }
B - Ignatius and the Princess IV
Topic link: B - Ignatius and the Princess IV
- Thought: Water.
Code:
#include <iostream> #include <cstdio> #include <cstring> #include <map> using namespace std; typedef long long LL; map<LL, LL> m; int main() { int N; LL a, ans; while(scanf("%d", &N)!=EOF) { m.clear(); int res = (N+1)/2; for(int i=0; i<N; i++) { scanf("%lld", &a); m[a]++; if(m[a]==res) ans = a; } printf("%lld\n", ans); } return 0; }
C - Monkey and Banana
Topic link: C - Monkey and Banana
D - Doing Homework
Topic link: D - Doing Homework
E - Super Jumping! Jumping! Jumping!
Topic link: E - Super Jumping! Jumping! Jumping!
- Idea: Simple variants of LIS can be applied from finding the length of the longest incremental subsequence to finding the sum of the longest incremental subsequence.
Code:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int main() { int N, a[1005], dp[10005]; while(cin >> N && N) { for(int i=1; i<=N; i++) cin >> a[i]; memset(dp, 0, sizeof(dp)); a[0] = -1<<29; int ans = 0; for(int i=1; i<=N; i++) { for(int j=0; j<i; j++) { if(a[j]<a[i]) dp[i] = max(dp[i], dp[j]+a[i]); } ans = max(ans, dp[i]); } cout << ans << endl; } return 0; }
F - Piggy-Bank
Topic link: F - Piggy-Bank
- Thought: A complete knapsack template problem, pay attention to the array do not open small...
Code:
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int INF = 1<<29; struct Node { int p, w; }; Node coin[1000]; int dp[10005];//Pay attention to the size of the array and turn down the possible TLE int main() { int T, E, F, N, n; scanf("%d", &T); while(T--) { scanf("%d%d", &E, &F); N = F-E; scanf("%d", &n); fill(dp, dp+N+1, INF); dp[0] = 0; for(int i=1; i<=n; i++) { scanf("%d%d", &coin[i].p, &coin[i].w); for(int j=coin[i].w; j<=N; j++) { dp[j] = min(dp[j], dp[j-coin[i].w]+coin[i].p); } } if(dp[N]==INF) printf("This is impossible.\n"); else printf("The minimum amount of money in the piggy-bank is %d.\n", dp[N]); } return 0; }