题目链接
https://www.qduoj.com/problem/93
题目大意
判断是否能将一组数平均分成两份。
解题思路
一看到这个题感觉好像做过,但还是没做出来。
我成功的当成贪心去算了,wa不停。
正解是01背包恰好装满:
找个sum/2的背包,sum为数和。
每件物品的是每个数,每个数的值既是体积大小,又是自身价值。
最后只要看dp[sum/2]是否等于sum/2就行,这意味着sum/2大小的背包装下了价值为sum/2的东西。
对应到本题而言,意味着存在一组数的和正好为sum/2。
错误的贪心代码(我的)
#include<bits/stdc++.h>
using namespace std;
const int N=205;
int a[N];
int sum1,sum2;
int n;
bool cmp(int x,int y){
return x>y;
}
int main(){
while(cin>>n){
sum1=0;sum2=0;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
sum1>sum2 ? sum2+=a[i] : sum1+=a[i];
cout<<(sum1==sum2 ? "YES" : "NO")<<endl;
}
}
//反例:5 4 3 2 2 AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=205;
const int M=N*100;
int dp[M];
int n,sum;
int a[N];
int main(){
while(cin>>n){
sum=0;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
}
if(sum&1){cout<<"NO"<<endl;}//判断为奇数
else{
memset(dp,0,sizeof dp);//勿忘
sum/=2;
for(int i=1;i<=n;i++)
for(int j=sum;j>=a[i];j--)
dp[j]=max(dp[j-a[i]]+a[i],dp[j]);
if(dp[sum]==sum)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
} 总结
感觉很简单一道题,而且好像还做过类似的,还是没做出来,我真的菜的抠jio。
还是要记住这种方法!!!
最后的最后,我还想再问上天一句:我什么时候才能成为大佬啊啊啊!!!

京公网安备 11010502036488号