专栏文章
UVA10482 The Candyman Can 题解
UVA10482题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqiufbm
- 此快照首次捕获于
- 2025/12/04 05:31 3 个月前
- 此快照最后确认于
- 2025/12/04 05:31 3 个月前
前记
正文
首先观察此题的 :
看给我激动的,暴力打起来。
这里可以考虑利用二维 ,设第一个孩子的糖果重量为 ,第二个孩子的糖果重量为 ,由于总量相同,所以第三个孩子的糖果重量为 ,则 就是表示这样的情况是否成立。
找一下状态转移方程:
如果 成立,那么 和 也一定成立。
最后考虑一下初始化:
,这个比较常规了。
来到最后的暴力搜答案,只需找到得到最大总重量糖果的孩子和得到最小总重量糖果的孩子在糖果重量上的最小差异是多少即可,也就是 , , 的最大值到 , , 的最小值中的最小值就可以(感觉好绕口啊)。
输出别忘了按格式输出!!!
这里可以考虑利用二维 ,设第一个孩子的糖果重量为 ,第二个孩子的糖果重量为 ,由于总量相同,所以第三个孩子的糖果重量为 ,则 就是表示这样的情况是否成立。
找一下状态转移方程:
如果 成立,那么 和 也一定成立。
最后考虑一下初始化:
,这个比较常规了。
来到最后的暴力搜答案,只需找到得到最大总重量糖果的孩子和得到最小总重量糖果的孩子在糖果重量上的最小差异是多少即可,也就是 , , 的最大值到 , , 的最小值中的最小值就可以(感觉好绕口啊)。
输出别忘了按格式输出!!!
代码:
CPP#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
//头文件可以用万能头
using namespace std;
typedef long long ll;
inline ll read(){
ll f=1,sum=0;char c=getchar();
while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
while(isdigit(c)) {sum=sum*10+c-'0';c=getchar();}
return sum*f;
}//经典快读模板
const int N=130+5;//n的取值
int num[N],dp[N][N];
void solve(int q,int m){
int minn=1e9,sum=0;//minn是答案,因为要取最小值,所以用了int的极限值,sum是计算总重
int n=read();
for(int i=1;i<=n;i++){
num[i]=read();
sum+=num[i];
}
memset(dp,0,sizeof(dp));//清空dp数组
dp[0][0]=1;//dp数组初始化
for(int i=1;i<=n;i++){
for(int j=sum;j>=0;j--){
for(int k=sum-j;k>=0;k--){
if(dp[j][k]){
dp[j+num[i]][k]=1;
dp[j][k+num[i]]=1;//状态转移方程
}
}
}
}//dp模板
for(int j=sum;j>=0;j--){
for(int k=sum-j;k>=0;k--){
if(dp[j][k]) minn=min(minn,max(max(j,k),sum-j-k)-min(min(j,k),sum-j-k));
}
}//暴力寻找答案
cout<<"Case "<<m-q<<": "<<minn<<endl;
//这里因为我用的是t--循环,所以要先用m记录原来t,用m减去现在的t(函数定义时换了个字母q)为编号
}
int main(){
int t=read();//多测
int m=t;//见solve函数最后一行
while(t--){
solve(t,m);
}//个人习惯
return 0;//完美地结束
}
后记
求关注awa,也求管理员通过awa。
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...