标签:stdin pac 行数据 print span dex amp 自我 ace
---恢复内容开始---
7.1,今日AC题目5到,今天为大家讲解一道普及组的深搜剪枝问题,这道题参解时需要在脑海及对应的手上模拟,切忌眼高手低,切忌三心二意
5 10
2 2 6 5 4
2 2 6
题解:
这道题的基本解题思想是用dfs枚举数组,计算数组的和。
但若是数据较大耗时较长,我们便须用剪枝来优化,对应的剪枝方法:
1.计算出后缀和数组sum[i]和后缀最小值数组mina[i]
2.对于sum[i]数组,在枚举过程中若是当前数组和cnt加上i的后缀和sum[i]小于c,则直接break跳出循环,当前dfs状态结束
3.对于mina[i]数组,在枚举过程中若是当前数组和cnt加上mina[i]>c,也是直接跳出循环,当前dfs状态结束,跳入下一状态
题解代码:
#include<iostream>
#include<string>
using namespace std;
int n;
long long c,a[7005],sum[7005],mina[7005],ans[7005],minn=0x3f3f3f3f,sum1=0;
bool flag=0;
void dfs(int index1,int index2,int cnt){
if(cnt>c) return ;
if(cnt==c){
for(int i=0;i<index2;i++){
printf("%lld ",ans[i]);
}printf("\n");
exit(0);
}
for(int i=index1+1;i<n;i++){
if(cnt+sum[i]<c) break;
if(cnt+mina[i]>c) break;
ans[index2]=a[i];
dfs(i,index2+1,cnt+ans[index2]);
}
}
int main(){
freopen("setsum.in","r",stdin);
scanf("%d%lld",&n,&c);
for(int i=0;i<n;i++){
scanf("%lld",&a[i]);
}
for(int i=n-1;i>=0;i--){
minn=min(minn,a[i]);
sum1+=a[i];
sum[i]=sum1;
mina[i]=minn;
}
/*
for(int i=0;i<n;i++){
printf("%lld %lld\n",sum[i],mina[i]);
}
*/
dfs(-1,0,0);
printf("No Solution!\n");
return 0;
}
反省与展望:
7.1日记住这一天,正如孙老师所说:追求卓越,成功便会在不经意间与你相遇
当今段位usaco青铜,坚持每天进步一点点,哪怕多刷一道题,多学10分钟英语,与樊浩,李俊辉大佬共同进步,争取早日超过孙西越大佬
争取早日拿下usaco金级段位,信息学竞赛,传统算法高级人才稀缺,高级教育人才有价无市,咸鱼翻身的机会就在眼前,哪怕只有一次机会,都应全力以赴
如今的我只能辅导入门组,而入门组能辅导的人太多了,争取在暑假尽快提升自我,将普及组的题刷完,辅导普及组,提升自我在第一位,挣钱在第二位,要挣就挣个大的。
博观而约取,厚积而薄发。
---恢复内容结束---
标签:stdin pac 行数据 print span dex amp 自我 ace
原文地址:https://www.cnblogs.com/cxs070998/p/11117549.html