动态规划12345

 

#include<bits/stdc++.h>
using namespace std;
 
int n, h, f[30][400], d[30], t[30], dp[30][400];
//dp[i][j]:前i个湖前j个单位时间的最大值 
 
int main()
{
    //freopen("in.txt","r",stdin);
    while (~scanf("%d", &n) && n)
    {
        memset(f, 0, sizeof(f));
        scanf("%d", &h);
        h = h * 12;
 
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &f[i][1]);
        }
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &d[i]);
        }
        for (int i = 2; i <= n; i++)
        {
            scanf("%d", &t[i]);
        }
        t[1] = 0;
 
        for (int i = 1; i <= n; i++)
        {
            for (int k = 2; k <= h; k++)
            {
                if (f[i][k - 1] <= d[i]) break;
                f[i][k] = f[i][k - 1] - d[i];
            }
        }
 
        memset(dp, -1, sizeof(dp));
        dp[0][0] = 0;
 
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j <= h; j++)
            {
                int sum = 0;
                for (int k = 0; k <= h && dp[i][j] != -1; k++) //在第i个湖钓k个单位时间
                {
                    if (j + t[i + 1] + k > h) break;
                    dp[i + 1][j + t[i + 1] + k] = max(dp[i][j] + sum, dp[i + 1][j + t[i + 1] + k]);
                    if (f[i + 1][k + 1] > 0) sum += f[i + 1][k + 1];
                }
            }
        }
 
        int mark = 1, MAX = 0;
        for (int i = 1; i <= n; i++)
        {
            if (MAX < dp[i][h])
            {
                MAX = dp[i][h];
                mark = i;
            }
        }
 
        int MMAX = MAX;
        for (int i = mark; i >= 2; i--)
        {
            int sum = 0, k;
            for (k = 0; k <= h; k++)
            {
                if (MAX == sum + dp[i - 1][h - k - t[i]])
                {
                    f[i][0] = k;
                    break;
                }
                sum = sum + f[i][k + 1];
            }
            h = h - t[i] - k;
            MAX -= sum;
        }
 
        f[1][0] = h;
        for (int i = 1; i < n; i++)
        {
            printf("%d, ", f[i][0] * 5);
        }
        printf("%d\n", f[n][0] * 5);
        printf("Number of fish expected: %d\n\n", MMAX);
    }
    return 0;
}
//A

#include<bitsdc++.h>
using namespace std;
int N, nums=0;
int len[10010],dp[10010];
int main() {
    cin >> N;
    string s;
    while (cin >> s) {
        nums++;
        len[nums] = len[nums - 1] + s.size();
    }
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= nums; i++) {
        if (len[i] - len[i - 1] == N) {
            dp[i] = dp[i - 1];
        }
        else {
            dp[i] = dp[i - 1] + 500; 
        }
        for (int j = i - 2; j >= 0; j--) {
            int tot = i - j - 1;
            int blanks = N - (len[i] - len[j]);
            if (blanks < tot) continue;
            int avg = blanks / tot;
            int rmd = blanks % tot;
            int s = rmd * (avg * avg) + (tot - rmd) * (avg - 1) * (avg - 1);
            dp[i] = min(dp[i], dp[j] + s);
        }
    }
    printf("Minimal badness is %d.\n", dp[nums]);
}
//B

#include <iostream>  
#include <cstring>
#include <algorithm>
 
using namespace std;
const int N = 1e4 + 10;
int nums[N];  // 存储数据 
int dp[N];    // dp[i]表示以第i个位置的数为结尾的最长不下降子序列的长度
int ans = 0;
 
int main() {  
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) scanf("%d", &nums[i]);
 
    for (int i = 1; i <= n; i++) dp[i] = 1;  // 初始化
 
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < i; j++) {
            if (nums[j] < nums[i]) 
                dp[i] = max(dp[j] + 1, dp[i]);
        }
        ans = max(dp[i], ans);
    }
    cout << ans << endl;
    return 0;
}

 

#include<bits/stdc++.h>
using namespace std;
 
int main()
{
    int n;
    int a[51][51][4];
    cin >> n;
    memset(a, 0, sizeof(a));
    while (n)
    {
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= i; j++)
            {
                cin >> a[i][j][1];
                a[i][j][2] = a[i][j][1];
                a[i][j][3] = 0;
            }
        for (int i = n - 1; i >= 1; i--)
            for (int j = 1; j <= i; j++)
            {
                if (a[i + 1][j][2] > a[i + 1][j + 1][2])
                {
                    a[i][j][2] = a[i + 1][j][2] + a[i][j][2];
                    a[i][j][3] = 0;
                }
                else
                {
                    a[i][j][2] = a[i + 1][j + 1][2] + a[i][j][2];
                    a[i][j][3] = 1;
                }
            }cout << a[1][1][2] << endl;
            int j = 1;
            for (int i = 1; i <= n - 1; i++)
            {
                j = j + a[i][j][3];
            }
            cin >> n;
    }
    return 0;
}
//D

 

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100000
int T[MAXN], dp[MAXN];
int main()
{
    int len = 0;
    while (scanf("%d",&T[len])!=EOF)
        ++len;
    dp[0]=1;
    int down_max=dp[0];
    for (int i=1;i<len;i++)
    {
        dp[i]=1;
        for (int j=0;j<i;j++)
        {
            if (T[j]>=T[i])
                dp[i]=max(dp[i],dp[j]+1);
        }
         
    }
     
    down_max=0;
    for (int i=0;i<len;i++) down_max=max(down_max,dp[i]);
 
    dp[0] = 1;
    int up_max = dp[0];
    for(int i=1; i<len; ++i)
    {
        //DP[i] = max{DP[k]+1,if(T[k]<T[i] && k<i)}
        int max_index = i; 
        for(int k=0; k<i; ++k)
            if(T[k]<T[i] && 
                (max_index==i || dp[k]>dp[max_index]))
                max_index = k;
        if(max_index == i)
            dp[i] = 1;
        else
            dp[i] = dp[max_index] + 1;
        if(dp[i] > up_max)
            up_max = dp[i];
    }
    printf("%d\n%d\n",down_max,up_max);
     
    return 0;
}
//E

 

#include<bitsdc++.h>
using namespace std;
typedef pair <int, int> P;
int n, ans, f[5005];
P p[5005];
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> p[i].first >> p[i].second;
    }
    sort(p + 1, p + n + 1);

    for (int i = 1; i <= n; i++){
        f[i] = 1;
        for (int j = 1; j < i; j++)
            if (p[i].second >= p[j].second) { f[i] = max(f[i], f[j] + 1); }
        ans = max(ans, f[i]);
    }
    cout << ans << endl;
    return 0;
}
//F

 

 

 

#include<bitsdc++.h>
using namespace std;
int n, ans, f[205],rec[205],a[205];
int c[205][205];
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    int x, y;
    while (cin >> x >> y && x || y) {
        c[x][y] = 1;
    }
    f[n] = a[n];
    for (int i = n - 1; i >= 1; i--) {
        int t = 0;
        int maxn = 0;
        for (int j = i + 1; j <= n; j++) {
            if (c[i][j] == 1 && f[j] > maxn) {
                maxn = f[j];
                t = j;
            }
        }
        f[i] = a[i] + maxn;
        rec[i] = t;
       // cout << rec[i] << " " << i << endl;
    }

    int s = 1;
    for (int i = 1; i <= n; i++) {
        if (f[i] > ans){
            ans = f[i];
            s = i;
        }
    }
    while (rec[s] != 0) {
        cout << s << "-";
        s = rec[s];
    }
    cout << s << endl;
    cout << ans << endl;
    return 0;
}
//H

#include <bits/stdc++.h>
using namespace std;
string s,t;
int dp[105][105];
int main()
{
    while (cin >> s >> t)
    {
        memset(dp, 0, sizeof(dp));
        int a = s.size();
        int b = t.size();
        for(int i=1;i<=a;i++)
            for (int j = 1; j <= b; j++)
            {
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                if (s[i - 1] == t[j - 1])
                    dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
            }
        cout << dp[a][b] << endl;
    }
    return 0;
}
//I

 

#include<bits/stdc++.h>
using namespace std;
int n, v, c[5050], w[5050], f[5050];
inline int read()
{
    int x = 0;
    char c = getchar();
    while (c < '0' || c>'9') c = getchar();
    while (c >= '0' && c <= '9')
    {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}
int main()
{
    n = read(); v = read();
    for (int i = 1; i <= n; i++)
    {
        c[i] = read();
        w[i] = read();
    }
 
    memset(f, 0, sizeof(f));//用给f赋一个较小值 
 
    for (int i = 1; i <= n; i++)//从第一行推到第n行,最后一次保存的就是第n行的f信息 
    {
        for (int j = v; j >= c[i]; j--)//从大到小推,注意容量要大于等于物体的体积 
        {
            f[j] = max(f[j], f[j - c[i]] + w[i]);
        }
    }
    printf("%d", f[v]);//输出前n个物品放入v容量背包的最大价值 
    return 0;
}
 
//J

 

 

#include<bitsdc++.h>
using namespace std;
int w[500000], v[500000], dp[5000000];
int main() {
	int m, n;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> w[i] >> v[i];
	}
	for (int i = 1; i <= m; i++) {
		for (int j = n; j >= 0; j--) {
			if (j >= w[i])dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
		}
	}
	cout << dp[n] << endl;
	return 0;
}
//K

 

#include <bitsdc++.h>
using namespace std;
int f[201], n;
bool  pri[201] = { 0 };
void add(int x){
	for (int i = x; i <= 200; i++) {
		f[i] += f[i - x];
	}
}
int main(){
	f[0] = 1, f[1] = 0;
	for (int i = 2; i <= 200; i++) {
		if (!pri[i]) {
			add(i);
			for (int j = i * i; j <= 200; j += i) {
				pri[j] = 1;
			}
		}
	}
	while (cin >> n) {
		cout << f[n] << endl;
	}
	return 0;
}
//L

 

问题 M: 完全背包问题

内存限制:128 MB时间限制:1.000 S
评测方式:文本比较命题人:外部导入
提交:286解决:122

题目描述

设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。

输入

第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);

第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

输出

仅一行,一个数,表示最大总价值。

样例输入 复制

10 4
2 1
3 3
4 5
7 9

样例输出 复制

max=12
#include<bits/stdc++.h>
using namespace std;
int n, m, f[10005];
struct node{
    int w;
    int c;
}d[105];
int main()
{
    scanf("%d%d", &m, &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d%d", &d[i].w, &d[i].c);
    }
    for (int i = 1; i <= n; i++)
        for (int v = 1; v <=m; v++)
        {
            if (d[i].w <= v)
                f[v] = max(f[v], f[v - d[i].w] + d[i].c);
            /*if (v < d[i].w) f[i][v] = f[i - 1][v];
            else
                if (f[i - 1][v] > f[i][v - d[i].w] + d[i].c) f[i][v] = f[i - 1][v];
                else 
                f[i][v] = f[i][v - d[i].w] + d[i].c;*/
        }
    printf("max=%d\n", f[m]);
    return 0;
}
//M

#include <bits/stdc++.h>
using namespace std;
int n, m, dp[1005][1005], v[1005][1005];
int main()
{
    cin >> m >> n;
    for (int i = 0; i <= m; i++)
        for (int j = 1; j <= n; j++)
        {
            cin >> v[j][i];
        }
    for (int i = 0; i <= m; i++)
    {
        dp[1][i] = v[1][i];
    }
    for (int i = 0; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            int maxn = 0;
            //find
            for (int xk = 0; xk <= j; xk++)
                maxn = max(maxn, v[i][xk] + dp[i - 1][j - xk]);
            dp[i][j] = maxn;
        }
    cout << dp[n][m] << endl;
    return 0;
}

 

问题 O: 0/1背包

题目描述

       一个旅行者有一个最多能用m公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn.若每种物品只有一件求旅行者能获得最大总价值。

输入

w第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);

w   第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

输出

仅一行,一个数,表示最大总价值。

样例输入 复制

10 4
2 1
3 3
4 5
7 9

样例输出 复制

12
#include<bits/stdc++.h>
using namespace std;
int n, m, f[10005];
struct node{
    int w;
    int c;
}d[105];
int main()
{
    scanf("%d%d", &m, &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d%d", &d[i].w, &d[i].c);
    }
    for (int i = 1; i <= n; i++)
        for (int v = m; v > 0; v--)
        {
            if (d[i].w <= v)
                f[v] = max(f[v], f[v - d[i].w] + d[i].c);
        }
    printf("%d\n", f[m]);
    return 0;
}
//O

问题 P: 庆功会

题目描述

      为了庆贺班级在校运动会上取得全校第一名成绩,班主任决定开一场庆功会,为此拨款购买奖品犒劳运动员。期望拨款金额能购买最大价值的奖品,可以补充他们的精力和体力。

输入

第一行二个数n(n<=500),m(m<=6000),其中n代表希望购买的奖品的种数,m表示拨款金额。

接下来n行,每行3个数,v、w、s,分别表示第I种奖品的价格、价值(价格与价值是不同的概念)和购买的数量(买0件到s件均可),其中v<=100,w<=1000,s<=10。

输出

第一行:一个数,表示此次购买能获得的最大的价值(注意!不是价格)。

样例输入 复制

5 1000 80 20 4 40 50 9 30 50 7 40 30 6 20 20 1

样例输出 复制

1040
#include<bits/stdc++.h>
using namespace std;
int v[6002], w[6002], s[6002], f[6002];
int n, m;
int max(int x, int y)
{
    if (x < y) return y;
    else return x;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d%d%d", &v[i], &w[i], &s[i]);
    for (int i = 1; i <= n; i++)
        for (int j = m; j >= 0; j--)
            for (int k = 0; k <= s[i]; k++)
            {
                if (j - k * v[i] < 0) break;
                f[j] = max(f[j], f[j - k * v[i]] + k * w[i]);
            }
    printf("%d", f[m]);
    return 0;
}
//P

问题 Q: 混合背包

题目描述

      一个旅行者有一个最多能用V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

输入

第一行:二个整数,V(背包容量,V<=200),N(物品数量,N<=30);

第2..N+1行:每行三个整数Wi,Ci,Pi,前两个整数分别表示每个物品的重量,价值,第三个整数若为0,则说明此物品可以购买无数件,若为其他数字,则为此物品可购买的最多件数(Pi)。

输出

仅一行,一个数,表示最大总价值。

样例输入 复制

10 3 2 1 0 3 3 1 4 5 4

样例输出 复制

11
#include<bits/stdc++.h>
using namespace std;
int main() {
    int V, n;
    scanf("%d%d", & V, & n);
    int w[n], c[n], p[n];
    for (int i = 0; i < n; i++) {
        scanf("%d%d%d", & w[i], & c[i], & p[i]);
    }
    int dp[V + 1000] = {
        0 
    };
    int ans = 0;
    for (int i = 0; i < n; i++) {
        if (p[i] == 0) { //p[i]等于0时,转化为完全背包求解
            for (int j = w[i]; j <= V; j++) {
                dp[j] = max(dp[j], dp[j - w[i]] + c[i]);
                ans = max(ans, dp[j]);
            }
        }
        else {
            for (int j = V; j >= w[i]; j--) {
                for (int l = 1; l <= p[i] && l * w[i] <= j; l++) {
                    dp[j] = max(dp[j], dp[j - l * w[i]] + l * c[i]);
                    ans = max(ans, dp[j]);
                }
            }
        }
    }
    printf("%d", ans);
    return 0;
}
//Q

 

 

#include<bitsdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int a[1005], b[1005], c[1005], dp[1005][1005];
int main() {
	int m, n, k;
	cin >> m >> n >> k;
	for (int i = 1; i <= k; i++) {
		cin >> a[i] >> b[i] >> c[i];
	}
	memset(dp, INF, sizeof(dp));
	dp[0][0] = 0;
	for (int i = 1; i <= k; i++) {
		for (int x = m; x >= 0; x--) {
			for (int y = n; y >= 0; y--) {
				if (dp[x][y] == INF) continue;
				int u = min(m, x + a[i]);
				int v = min(n, y + b[i]);
				dp[u][v] = min(dp[u][v], dp[x][y] + c[i]);
			}
		}
	}
	cout << dp[m][n] << endl;
	return 0;
}
//R

#include<bitsdc++.h>
using namespace std;
int w[1000], c[1000], p[1000],dp[100000];
struct A {
	int a[1005];
	int b[1005];
	int len = 0;
}t[1000];
int main() {
	int V, N, T, l = 0;
	cin >> V >> N >> T;
	for (int i = 1; i <= N; i++) {
		cin >> w[i] >> c[i] >> p[i];
		l = ++t[p[i]].len;
		t[p[i]].a[l] = w[i];
		t[p[i]].b[l] = c[i];
	}
	for (int i = 1; i <= T; i++) {
		for (int j = V; j >= 0; j--) {
			for (int k = 1; k <= t[i].len; k++) {
				if (j >= t[i].a[k]) {
					dp[j] = max(dp[j], dp[j - t[i].a[k]] + t[i].b[k]);
				}
			}
		}
	}
	cout << dp[V] << endl;
	return 0;
};
//S

 

#include<bitsdc++.h>
using namespace std;
long long v[100005], dp[100005],ans;
int main() {
	long long m, n;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> v[i];
	}
	dp[0] = 1;
	for (int i = 1; i <= n; i++){
		for (int j = v[i]; j <= m; j++) {
			dp[j] += dp[j - v[i]];
		}
	}
	cout << dp[m] << endl;
}
//T

 

 

#include<bits/stdc++.h>
using namespace std;
int n, sum, maxn = -INT16_MAX, a[100001];
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    sum = 0;
    for (int i = 1; i <= n; i++)
    {
        sum += a[i];
        if (sum > maxn)
            maxn = sum;
        if (sum < 0)
            sum = 0;
    }
    cout << maxn <<endl;
    return 0;
}
//最后一个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值