喻某的米


私信TA

用户名:uq_31086138672

访问量:2574

签 名:

下一个自己加油

等  级
排  名 67
经  验 10385
参赛次数 4
文章发表 4
年  龄 0
在职情况 待业
学  校
专  业 软件工程

  自我简介:

解题思路:

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分

6 人评分

  评论区

  • «
  • »