蓝桥杯集训——普及组(c++)

Libert_AC 2023-02-06 23:14:00

第一题:经典01背包

P1048 [NOIP2005 普及组] 采药 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

f[i, j] 表示从前 i 个草药里面采,花费时间不超过 j 的最大价值

优化成一维,从前往后遍历,确保每次上一层被计算

#include<iostream>
using namespace std;

const int N = 1010;
int f[N];
int n, m;

int main(){
    cin>>m>>n;
    
    for(int i = 1; i <= n; i++){
        int v, w;
        cin>>v>>w;
        for(int j = m; j >= v; j--)
            f[j] = max(f[j], f[j-v] + w);
    }
    
    cout<<f[m]<<endl;
    return 0;
}

第二题:完全背包模板

P1616 疯狂的采药 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

注意数据范围就行

#include<iostream>
using namespace std;

typedef long long LL;
const int N = 1e7 + 5;
LL f[N];
LL n, m;

int main(){
    scanf("%lld%lld", &m, &n);
    
    for(int i = 1; i <= n; i++){
        LL v, w;
        scanf("%lld%lld", &v, &w);
        for(int j = v; j <= m; j++)
            f[j] = max(f[j] , f[j-v] + w);
    }
    
    printf("%lld", f[m]);
    return 0;
}

第三题: (129条消息) 摘花生(数字三角形模型)_今天取什么名字好啊的博客-CSDN博客

对于每组数据进行处理,这是一道数字三角形模型衍生题

使用闫式分析法即可,f数组表示到达(i, j ) 时能够摘到的最多花生数量

有两种可能,分别是从左边来的,从上面来的,每次取每步方案的最大值,再加上本身的数量

#include<iostream>
#include<cstring>
using namespace std;
 
const int N = 110;
int n;
int a[N][N], f[N][N];
 
int main(){
    scanf("%d", &n);
    
    while(n--){
        int r, c;
        scanf("%d%d", &r, &c);
        memset(a, 0, sizeof a);
        memset(f, 0, sizeof f);
        
        for(int i = 1; i <= r; i++)
            for(int j = 1; j <= c; j++)
                scanf("%d", &a[i][j]);
        
        for(int i = 1; i <= r; i++)
            for(int j = 1; j <= c; j++)
                f[i][j] = max(f[i][j-1], f[i-1][j]) + a[i][j];
                
        printf("%d\n", f[r][c]);
    }
 
    
    return 0;
}

第四题:多重背包

P1077 [NOIP2012 普及组] 摆花 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

注意k的取数,二维要从0开始,因为 f[i-1,j-k]

f[i,j]表示从前 i 个物品里面选,不超过 j 盆的合理方案数量

状态计算:

1、不取   f[i-1, j]

2、取      f[i-1, j-k]    k的范围( 0 ~ min(a[i],j ) )

#include<iostream>
using namespace std;

const int N = 110, MOD = 1000007;;
int n, m;
int f[N], a[N];

int main(){
    cin>>n>>m;
    
    for(int i = 1; i <= n; i++) cin>>a[i];
    
    f[0] = 1;  //从0个里面选不超过0盆也是一种方案
    for(int i = 1; i <= n; i++)
        for(int j = m; j >= 0; j--)
            for(int k = 1; k <= min(j, a[i]) ; k++)  //k要从1开始因为f[j-k]不能多加一次
                f[j] = (f[j] + f[j-k]) % MOD;
                
    cout<<f[m]<<endl;
    return 0;
}

 

...全文
21 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

50,779

社区成员

发帖
与我相关
我的任务
社区描述
和众多高校算法内卷分子,一起学习和交流算法那。浓郁的算法交流氛围,拒绝躺平,有效内卷。加入我们,私信我拉你入核心内卷群。
算法数据结构leetcode 个人社区
社区管理员
  • 执 梗
  • Dream-Y.ocean
  • ღCauchyོꦿ࿐
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

 刷题!

试试用AI创作助手写篇文章吧