蓝桥杯-线性动态规划问题&背包问题进阶策略详解(题目及解题代码)

 题目:蓝桥云课-青蛙吃虫

解题代码:

#include <iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=106;

int f[N][N];
int a[N]; 
int t,l,r,k,n;

int main()
{
	cin>>t;
	
	while(t--){
		scanf("%d%d%d%d",&n,&l,&r,&k);
		
		memset(f,-0x3f,sizeof f);
		f[0][0]=0;
		
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		
		for(int i=1;i<=n;i++){
			for(int j=1;j<=k;j++){
				for(int k=l;k<=r;k++){
					if(i-k>=0){
						f[i][j]=max(f[i][j],f[i-k][j-1]+a[i]);
					}else{
						break;
					}
				}
			}
		}
		
		int ans=0;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=k;j++){
				ans=max(ans,f[i][j]);
				//cout<<f[i][j]<<" ";
			}
			//cout<<endl;
		}
		
		printf("%d\n",ans);
	}
  	return 0;
}

 题目:15 届蓝桥杯14天国特冲刺营 - 奇怪的段 - 蓝桥云课 (lanqiao.cn)

解题代码:

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N=1e5+6;

typedef long long ll;

ll f[N][206];
ll a[N];
ll sum[N];
ll p[206];
int n,k;

int main(){
	cin>>n>>k;
	
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		sum[i]=sum[i-1]+a[i];
	}
	
	memset(f,-0x3f,sizeof f);
	f[0][0]=0;
	
	for(int i=1;i<=k;i++) scanf("%lld",&p[i]);
	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=k;j++){
			f[i][j]=max(f[i-1][j]+p[j]*a[i],f[i-1][j-1]+a[i]*p[j]);
		}
	} 

	cout<<f[n][k];
	return 0;
} 

题目:

15 届蓝桥杯14天国特冲刺营 - 金明的预算方案 - 蓝桥云课 (lanqiao.cn)

解题代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>

using namespace std;

const int N=33000;

int f[N];
int v[N];
int imp[N];
int val[N];
int que[N];
vector<int> vc[N];

int n,m;

int main(){
	cin>>n>>m;
	
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&v[i],&imp[i],&que[i]);
		val[i]=v[i]*imp[i];
		
		if(que[i]){
			vc[que[i]].push_back(i);
		}
	}
	
	for(int i=1;i<=m;i++){
		if(que[i]==0){
			for(int j=n;j>=0;j--){
				if(j>=v[i]) 
					f[j]=max(f[j],f[j-v[i]]+val[i]);
				if(vc[i].size()>0&&j>=v[i]+v[vc[i][0]]) 
					f[j]=max(f[j],f[j-v[i]-v[vc[i][0]]]+val[i]+val[vc[i][0]]);
				if(vc[i].size()>1&&j>=v[i]+v[vc[i][0]]+v[vc[i][1]])
					f[j]=max(f[j],f[j-v[i]-v[vc[i][0]]-v[vc[i][1]]]+val[i]+val[vc[i][0]]+val[vc[i][1]]);
			}
		}
	}
	
	cout<<f[n];
	return 0;
} 

题目:

15 届蓝桥杯14天国特冲刺营 - 包子凑数 - 蓝桥云课 (lanqiao.cn)

解题代码: 

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5;
int dp[maxn], a[105];//dp[i]代表拿i个包子是否可能,1表示可能,0表示不可能 

int gcd(int a, int b) {
    return b?gcd(b,a%b):a;
}
int main() {
    int n, g, num = 0;
    cin>>n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    g = gcd(a[0], a[1]);
    for (int i = 2; i < n; i++) {
        g = gcd(g, a[i]);
    }//两两求最大公因子
    if (g != 1) cout << "INF" << endl;   //不互质,则有无限种都不能表示 
    else {
        dp[0] = 1;//0个包子肯定可以
        for (int i = 0; i < n; i++) {
            for (int j = 0; j +a[i]< maxn; j++) {
                if (dp[j]) {
                    dp[j + a[i]] = 1;
                }
            }
        }
        for (int i = 0; i < maxn; i++) {
            if(!dp[i]) {
                num++;
            }
        }
        cout << num << endl;
    }
    return 0;
}

 题目:

15 届蓝桥杯14天国特冲刺营 - 小明的背包4 - 蓝桥云课 (lanqiao.cn)

解题代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=1e5+6;

int n,vsum;
int listw[N];
int listv[N];
int f[N];

int main(){
	cin>>n>>vsum;
	
	int w,v,s;
	int cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d%d",&w,&v,&s);
		
		if(s==0) s=vsum/w;
		
		int t=1;
		while(s>t){
			s-=t;
			cnt++;
			listw[cnt]=t*w;
			listv[cnt]=t*v;
			
			t<<=1;
		} 
		cnt++;
		listw[cnt]=s*w;
		listv[cnt]=s*v;
	}
	
	
//	for(int i=1;i<=cnt;i++){
//		cout<<listw[i]<<":"<<listv[i]<<" ";
//	}
//	cout<<endl;
	
	
	for(int i=1;i<=cnt;i++){
		for(int j=vsum;j>=listw[i];j--){
			f[j]=max(f[j],f[j-listw[i]]+listv[i]);
		}
		
//		for(int j=1;j<=vsum;j++){
//			cout<<f[j]<<" ";
//		}
//		cout<<endl;
	}
	
	cout<<f[vsum];
	return 0;
}

题目:

15 届蓝桥杯14天国特冲刺营 - 李白打酒 - 蓝桥云课 (lanqiao.cn) 

解题代码:

#include<iostream>
using namespace std;

typedef long long ll;

const ll N=106,M=1000000007;

ll f[N][N][1006];
ll n,m;

int main(){
	cin>>n>>m;
	
	f[0][0][2]=1;
	for(int i=0;i<=n;i++){
		for(int j=0;j<=m;j++){
			for(int k=0;k<=m;k++){
				if(k%2==0 && i>=1) f[i][j][k]+=f[i-1][j][k/2];
				if(j>=1) f[i][j][k]+=f[i][j-1][k+1];
				f[i][j][k]%=M;
			}
		}
	}
	
	cout<<f[n][m-1][1];
	return 0;
} 

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CTGU-Yoghurt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值