#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 9;
const int M = 2e4 + 9;
bool dp[N][M]; //表示考虑前i件宝藏,能否拿到重量为M的宝藏
int a[N];
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n; cin >> n;
int sum = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}
if(sum & 1)
{
cout << "no" << '\n';
return 0;
}
for (int i = 1; i <= n; i++) dp[i][0] = true;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= sum; j++)
{
//拿与不拿
//不拿
dp[i][j] = dp[i-1][j];
//拿
if(j >= a[i]) dp[i][j] = dp[i][j] | dp[i-1][j-a[i]];
}
}
if (dp[n][sum / 2]) cout << "yes" << '\n';
else cout << "no" << '\n';
return 0;
}


//本题的难点仍在于状态转移方程的设计与列写
//由于两台机器完全相同,若总时间为sum,其中一台洗车时间为i,则另一台洗车时间为sum-i
//i与sum-i中的较大值即为最终答案
//故本题可以只考虑其中一台机器,枚举其所有洗车方案(可能花费的洗车时间)并使用动态规划验证该方案是否可行
//最终遍历该台机器所有可行的洗车方案,计算并比较出最终的洗车时间
//注:本题有一种错误解法,即把数组排序以后令两台机器分别从头和尾开始往中间遍历洗车
//这种解法是基于贪心思想的,但它并不能保证两台机器的洗车时间尽可能的接近,因此无法得出正确答案
//事实上在允许的时间复杂度内,本题并不存在直接找出最佳洗车方案的算法,
//只能使用动态规划来验证每一种洗车方案,然后比较得出最终答案
#include <bits/stdc++.h>
using namespace std;
int Time[109];
bool dp[109][10009];
//dp[i][j]表示只考虑前i辆车(每辆车可能洗或不洗),能否使总洗车时间为j,若能则为true
int main()
{
int N;
int sum=0;
int ans=1e9;
cin>>N;
for(int i=1;i<=N;i++)
{
cin>>Time[i];
sum=sum+Time[i];//计算总洗车时间
}
for(int i=0;i<=N;i++)dp[i][0]=true;//初始化,若该机器总洗车时间为0,必然能做到
for(int i=1;i<=N;i++)//遍历每一种可能的洗车方案,依次考虑前1~N辆车
{
for(int j=0;j<=sum;j++)//对于每一种洗车方案,遍历该机器所有可能的洗车时间,可能花0~sum分钟
{
//若洗前i-1辆车的时间为j-Time[i],则洗前i辆车的时间可以是j(洗第i辆车)
//若洗前i-1辆车的时间为j,则洗前i辆车的时间也可以是j(不洗第i辆车)
//两种情况满足其一,dp[i][j]即为true
//此处注意j-Time[i]要大于等于0,故分开写(合在一起写会有一个测试点错误)
//if (dp[i-1][j-Time[i]] == true) {
// dp[i][j] = true;
//}
dp[i][j]=dp[i-1][j];//初始化dp[i][j]表示不洗第i辆车的时候所消耗的时间等于洗第i-1辆车的时候消耗的时间
if(j>=Time[i])
{
dp[i][j]= dp[i][j] | dp[ i - 1 ][ j - Time[i] ];
//如果当前时间j大于等于第i辆车的洗车时间Time[i],
//则考虑洗第i辆车的情况。此时,前i辆车在j分钟内洗车的状态可以是前i-1辆车在j-Time[i]分钟内洗车的状态。
}
}
}
for(int i=1;i<=sum;i++)//遍历其中一台机器所有可能的洗车时间1~sum
{
if(dp[N][i])//若对于前N辆车,该机器洗车时间可以是i
{
int tmp=max(sum-i,i);//则对于该洗车方案,两台机器洗车完成的时间是sum-i和i之间的较大值
if(tmp<ans)ans=tmp;//比较得出所有洗车方案所花时间的最小值
}
}
cout<<ans<<endl;
return 0;
}

512

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



