标签:栅栏 now return int mid wh SCOI2005 木条
搜索题。
我真的不想写搜索啊,这玩意复杂度没法证,能拿多少分得看数据和评测机,而且没有固定思路,就像某些埋头堆硬件的厂家,写起来只有那么难受了。
关于这道题。有一个显而易见的贪心,最后锯出来的木条一定是最小的那些,因为长木条可以锯出来,短木条一定可以,转换方案之后肯定是不劣的。然后就考虑二分,用 f(wh) 来代表 wh 到 mid 的木条选完之后的状态,之前的影响则直接强加在木材数组里(感觉还是很巧妙的)。有两个剪枝,一个是假如两个木条长度一样,那么第二个木条的选择位置不会比第一个更靠前。第二个是假如当前木材已经比最短的木条短,那么它就是被浪费的。浪费的长度累加到一定程度就可以直接返回。
这玩意得多练。
#include<bits/stdc++.h>
//#define feyn
const int N=1010;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int m,n,all,now,a[N],b[N],sum[N];
bool dfs(int wh,int last,int waste){
if(wh==0)return true;
if(waste+now>all)return false;
for(int i=last;i<=n;i++){
if(a[i]>=b[wh]){
a[i]-=b[wh];
if(a[i]<b[1])waste+=a[i];
bool an=b[wh]==b[wh-1]?dfs(wh-1,i,waste):dfs(wh-1,1,waste);
if(a[i]<b[1])waste-=a[i];
a[i]+=b[wh];
if(an)return true;
}
}
return false;
}
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
read(m);
for(int i=1;i<=m;i++){
read(a[i]);all+=a[i];
}
read(n);
for(int i=1;i<=n;i++)read(b[i]);
sort(b+1,b+n+1);
int l=0,r=0,mid;
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+b[i];
if(sum[i]<=all)r=i;
else break;
}
while(l<r){
mid=l+r+1>>1;now=sum[mid];
if(dfs(mid,1,0))l=mid;
else r=mid-1;
}
printf("%d",l);
return 0;
}
标签:栅栏,now,return,int,mid,wh,SCOI2005,木条 来源: https://www.cnblogs.com/dai-se-can-tian/p/16446305.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。