$ ACM $ Lesson 4 Homework-Dynamic Programming

\ (ACM \) class fourth assignment-dynamic programming


\(A.\ Pearls\)

Title

Given \ (n \) pearls, each pearl has attributes \ (a_ {i}, \ p_ {i} \) , representing the quantity and price of demand, respectively, and the pearls are listed in order of ascending quality

Allow high-quality pearls to replace low-quality pearls

Each purchase needs to add the price of \ (10 ​​\) current quality pearls

Find the minimum amount of pearls you need to buy

Input format

Multiple sets of data, \ (n \ leq 100, \ a_ {i}, \ p_ {i} \ leq 1000 \)

Output format

Output minimum amount

answer

Observation found that if high-quality pearls are used instead of low-quality pearls, they must be continuous

Consider using the price combination of the \ (j \) pearl to buy \ (i, \ i + 1, \ ... \, \ j \) pearls, and purchase the \ (k, \ i <k <j \ ) A pearl, assuming that such a purchase method is optimal

You can buy \ (i, \ i + 1, \ ... \, \ k \) pearls at the price of the \ (k \) th pearl, so the price is less, so the combination purchase must be continuous

Definition \ (dp [i] \) is the minimum amount spent to purchase the first \ (i \) pearl

then

\[dp[i] = max\left\{dp[j - 1],\ (sum[i] - sum[j - 1] + 10)\cdot p[i],\ 1\leq j\leq i\right\} \]

\(code\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 5e2 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;

inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
    return ans * f;
}

int t, n, a[107], p[107], sum[107], dp[107];
int main()
{
    t = read();
    while(t--) {
        memset(dp, inf, sizeof(dp));
        dp[0] = 0;
        n = read();
        for(int i = 1; i <= n; ++i)
            a[i] = read(), p[i] = read();
        for(int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + a[i];
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= i; ++j) {
                dp[i] = min(dp[i], dp[j - 1] + (sum[i] - sum[j - 1] + 10) * p[i]);
            }
        }
        printf("%d\n", dp[n]);
    }
    return 0;
}
/*
6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 -3 -2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0
*/


\ (B. \) Maximum continuous subsequence

Title

Given a sequence of length \ (n \) , the largest continuous subsequence, record the head and tail

Input format

Multiple sets of data, \ (n \ leq 10000 \)

Output format

The maximum value of the output sum, and the corresponding head and tail

If there are multiple answers, the output is the smallest in lexicographic order

If the sum is negative, output \ (0, \ 1, \ n \)

answer

Define \ (dp [i] \) as the maximum value of the sum of subsequences ending in \ (a [i] \)

\[dp[i] = max\left\{dp[i - 1] + a[i],\ a[i]\right\} \]

After recording the maximum value \ (ans \) , scan the array again to find the beginning and end

\(code\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 5e2 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;

inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
    return ans * f;
}

int t, n, a[10007], dp[10007];
int main()
{
    while(scanf("%d", &n) && n) {
        for(int i = 1; i <= n; ++i) a[i] = read();
        int ans = -inf, head = 0, tail = 0;
        for(int i = 1; i <= n; ++i) {
            dp[i] = max(dp[i - 1] + a[i], a[i]);
            ans = max(ans, dp[i]);
        }
        if(ans < 0) ans = 0, head = 1, tail = n;
        else {
            for(int i = 1; i <= n; ++i) {
                if(dp[i] == ans) {
                    int temp = ans;
                    head = tail = i;
                    for(int j = i; temp; temp -= a[j], j--)
                        head = j;
                    break;
                }
            }
        }
        printf("%d %d %d\n", ans, a[head], a[tail]);
    }
    return 0;
}
/*
6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 -3 -2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0
*/

\(C.\ To\ The\ Max\)

Title

Given the matrix of \ (N \ times N \) , find the sum of the largest submatrix

Input format

Multiple sets of data, \ (N \ leq 100 \)

Output format

Output maximum submatrix sum

answer

Maintain 2D prefix and

Enumerate the upper left and lower right corners of the sub-matrix, use the difference \ (O (1) \) to calculate the sum

\(code\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 1e7 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;

inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
    return ans * f;
}

int n, a[107][107], dp[107][107];
int main()
{
    while(cin >> n) {
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j)
                a[i][j] = read();
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= n; ++j) {
                dp[i][j] = a[i][j] + dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1];
                //cout<<i<<' '<<j<<' '<<dp[i][j]<<endl;
            }
        }
        int ans = -inf;
        for(int s = 1; s <= n; ++s) {
            for(int t = 1; t <= n; ++t) {
                for(int i = 1; i <= s; ++i) {
                    for(int j = 1; j <= t; ++j) {
                        ans = max(ans, dp[s][t] - dp[i - 1][t] - dp[s][j - 1] + dp[i - 1][j - 1]);
                        //if(dp[s][t] - dp[i - 1][t] - dp[s][j - 1] + dp[i - 1][j - 1] == 23) cout<<i<<' '<<j<<' '<<s<<' '<<t<<endl;
                    }
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
/*
4
-1 -1 -1 -1
-1 -1 -1 -1
-1 -1 -1 -1
-1 -1 -1 -1
*/

\(D.\ Piggy\ Bank\)

Title

\ (n \) items, each item has two attributes of \ (p_ {i}, \ w_ {i} \) , which respectively represent the amount and capacity, which can be taken multiple times

Given a backpack with a capacity of \ (W = F-E \) , find the minimum amount of money needed to fill the backpack

Input format

Multiple sets of data, \ (n \ leq 500, \ E, \ F, \ W \ leq 10000, \ P \ leq 50000 \)

Output format

If it can be fully filled, output the minimum amount

If it cannot be filled up completely, output "impossible"

answer

Complete backpack

\(code\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9 + 7;
const int N = 5e2 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;

inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
    return ans * f;
}

int t, e, f, n, v[N], w[N], dp[10007];
int main()
{
    t = read();
    while(t--) {
        memset(dp, inf, sizeof(dp));
        dp[0] = 0;
        e = read(), f = read();
        n = read();
        for(int i = 1; i <= n; ++i) v[i] = read(), w[i] = read();
        for(int i = 1; i <= n; ++i)
            for(int j = w[i]; j <= (f - e); ++j)
                dp[j] = min(dp[j], dp[j - w[i]] + v[i]);
        //cout<<inf<<endl;
        if(dp[(f - e)] != inf) printf("The minimum amount of money in the piggy-bank is %d.\n", dp[(f - e)]);
        else puts("This is impossible.");
    }
    return 0;
}
/*
3
10 110
2
1 1
30 50
10 110
2
1 1
50 30
1 6
2
10 3
20 4
*/

Guess you like

Origin www.cnblogs.com/ChenyangXu/p/12723693.html