演算法提高 求最大值 DP
以下n行每行兩個整數 ai bi 輸出格式 輸出你選定的數對的ai+bi之和 樣例輸入 5
-403 -625
-847 901
-624 -708
-293 413
886 709 樣例輸出 1715 資料規模和約定 1<=n<=100
-1000<=ai,bi<=1000
DP[i][j]=k. 表示的是利用前i個, a的和為j時,b的和為k。
那麼dp[i][j]=max(dp[i][j],dp[i-1][j]);
如果j-a[u]存在,則dp[i][j]=max(dp[i][j],dp[i-1][ja[u]]+b[i];
輸出時遍歷j,ans=max(ans,j+dp[n-1][j])
由於a的和的和可能是負的,我們都加一個100000,保證他是正的
#include<bits/stdc++.h>
using namespace std;
int a[110];
int b[110];
int dp[110][210000];//用前i個組成a和為j的情況,b的和為多少
int n,p,q;
int t=100000;
const int INF = 0x3f3f3f3f;
int solve(int n)
{
for(int i=0;i<n;i++)
{
for(int j=-t;j<=t;j++)
{
dp[i][j+t]=-INF;
}
}
for(int i=0;i<n;i++)
{
dp[i][a[i]+t]=b[i];
}
for(int i=1;i<n;i++)
{
for(int j=-t;j<=t;j++)
{
dp[i][j+t]=max(dp[i-1][j+t],dp[i][j+t]);
if(j+t-a[i]>=0&&j+t-a[i]<=200000)
dp[i][j+t]=max(dp[i][j+t],dp[i-1][j+t-a[i]]+b[i]);
}
}
int ans=-INF;
for(int j=0;j<=t;j++)
{
if(dp[n-1][j+t]>=0)
ans=max(ans,j+dp[n-1][j+t]);
else
ans=max(ans,-INF);
}
return ans;
}
int main()
{
cin>>n;
int cnt=0;
for(int i=0;i<n;i++)
{
cin>>p>>q;
if(p<0&&q<0)
{
continue;
}
a[cnt]=p;
b[cnt]=q;
cnt++;
}
int ans=solve(cnt);
if(ans<=-INF)
{
cout<<"0"<<endl;
}
else
{
cout<<ans<<endl;
}
}