话不多说,直接献上题解:
无注释版:
#include<bits/stdc++.h>
using namespace std;
int n,a[505],sum,ans;
int dp[505][100005];
int main(){
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum += a[i] ;
}
memset(dp,-0x3f,sizeof(dp));
dp[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=sum;j++)
{
dp[i][j]=dp[i-1][j];
dp[i][j]=max( dp[i][j] , max( dp[i-1][j+a[i]]+a[i] , dp[i-1][abs(j-a[i])]+a[i] ) );
}
}
ans=sum-dp[n][0]/2;
cout<<ans;
}
有注释版:
#include<bits/stdc++.h>
using namespace std;
int n,a[505],sum,ans;
int dp[505][100005];
//dp[i][j] 表示前i张前中,使两人相差为 j
//且没有放到剩余堆的最多的钱
//dp[i][j] = dp[i-1][j] 把第i张
//钱放到剩余那堆里
//dp[i][j] = dp[i-1][j+a[i]]+a[i] 把
//第i张钱给当前钱少的,差距由j+a[i]缩小到j
//dp[i][j] = dp[i-1][abs(j-a[i])] 把第i张钱
//给当前钱多的
//当前钱多的有2种可能,之前就比钱少的多或拿到d
//第i张钱后反超回来
int main(){
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum += a[i] ;
}
memset(dp,-0x3f,sizeof(dp));//赋为极大负值,因为dp[i][j]表示的为差距
dp[0][0]=0;//如果赋为0,则在到 可行值 之前就有可能得到比可行值还大的值(血的教训!!!)
for(int i=1;i<=n;i++)
{
for(int j=0;j<=sum;j++)
{
dp[i][j]=dp[i-1][j];
dp[i][j]=max( dp[i][j] , max( dp[i-1][j+a[i]]+a[i] , dp[i-1][abs(j-a[i])]+a[i] ) );
}
}
ans=sum-dp[n][0]/2;
cout<<ans;
}
求求了!!!点个赞吧!!!
1187

被折叠的 条评论
为什么被折叠?



