解题思路:

1.固定a的和,在这种组合下找出b最大的和

2.dp[i][j]在前i种的情况下,a的和为j,b的和最大为dp[i][j]

3.状态转移方程式 dp[i][j]=max(  dp[i-1][j](没选a[i]) ,dp[i-1][j-a[i]](选了a[i])  )


注意事项:a的和有可能为负数,下标不能表示负数,对a的和偏移100000,最后结果减去100000


参考代码:

#include<cstdio>
#include<iostream>
#include<string.h>
#define INF 0x6666
#define N 100000
using namespace std;
int n,a[105],b[105],dp[101][2*N+8];
int ans;
void init(){
    cin>>n;
    for(int i=1;i<=n;i++){
        int x,y;
        cin>>x>>y;
        a[i]=x,b[i]=y;
    }
}//输入数据

void f(){
    memset(dp,-INF,sizeof(dp));
    for(int i=1;i<=n;i++)dp[i][a[i]+N]=b[i];
    for(int i=2;i<=n;i++){
        for(int j=0;j<=2*N;j++){
            dp[i][j]=max(dp[i][j],dp[i-1][j]);
            if(j-a[i]<0)continue;
            if(j-a[i]>2*N)break;//此时的j-a[i]大于了20w,证明a[i]<0,可以跳出内层循环
            dp[i][j]=max(dp[i][j],dp[i-1][j-a[i]]+b[i]);
        }
    }
    ans=0;//总和最小的和为0
    for(int i=N;i<=2*N;i++){
        if(dp[n][i]>=0)ans=max(ans,dp[n][i]+i-N);
    }
}//动态规划的函数

int main(){
    init();
    f();
    if(ans==0)cout<<"0";
    else cout<<ans;
    return 0;
}


点赞(0)
 

0.0分

6 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论