您的位置:首页 > 其它

蓝桥杯 算法提高 求最大值

2018-01-01 13:46 218 查看
转载一下ac代码,还是不太懂,,

转自
http://blog.csdn.net/a568283992/article/details/78574572
#include<iostream>
#include<algorithm>
using namespace std;

#define INF 0x3f3f3f3f
#define t 100000 //我们将每个元素+t后存储,以100000为'0'
#define N 200001 //每个元素之和最大不会超过20w,所以背包容量最大也就为N-1
int dp[105]
; //dp[i][j]代表前i个元素中,最大所有b[i]元素和的值,j为a[i]满足的容量,也就是说把a[i]当成背包容量,b[i]为价值,不过a需要加上t,避免负数
int A[105],B[105];

int getAns(int len){

for(int i = 0;i<len;i++){ //刚开始需要对dp总每个容量的进行初始化,都为-INF,因为b[i]的累加有可能是负数,所以不能初始化为0!,必须初始化为小于-200000,因此取-INF
for(int j = 0;j<N;j++)
dp[i][j] = -INF;
}

for(int i = 0;i < len;i++)
dp[i][A[i] + t] = B[i]; //这步是必须的,dp开始前的初值设置,表示当前前i个中,b[j]和最大的值为B[i],当然只是初试设置,可能随着程序运行改变其j所在的值

for(int i = 1;i < len;i++){
for(int j = 0;j<=N;j++){//遍历0 - N之间所有容量,类似01背包的转移方程
dp[i][j] = max(dp[i][j],dp[i-1][j]);
if(j - A[i] < 0 || j-A[i] > N-1)continue;
dp[i][j] = max(dp[i][j],dp[i-1][j-A[i]]+B[i]);
}
}

int result = -INF;
for(int j = 0;j<=t;j++){ //最后需要筛选符合的,因为有负数,所以必须从大于100000的地方开始找b[j]最大和,找到符合j+dp[len-1][j+t]的最大,就是符合条件的
//如果结果没变,说明没有符合的条件,输出0
if(dp[len-1][j+t]>=0){
result = max(result,dp[len-1][j+t]+j);
}
}
return result;
}

int main(){

int n;
cin>>n;
int len = 0;
for(int i = 0;i<n;i++){
int x,y;
cin>>x>>y;
if(x < 0 && y < 0)continue;//把都是负数的值剔除,没必要参与运算
A[len] = x;
B[len++] = y;
}

int ans = getAns(len);
if(ans <= -INF)cout<<0<<endl;
else cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: