bzoj1082: [SCOI2005]栅栏
2016-08-19 11:01
295 查看
二分答案+搜索。
难点是如何不超时。
解决这个问题我用了一些奇技淫巧,当然好多都是借鉴大神们的解法。
1.if (waste+need>all) return 0;
2. if (b[k]==b[k-1])
{
if (dfs(k-1,i)) return 1;
}
最后发现还是超时,然后去掉了几个头文件就过了......
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1111;
const int MAXM=55;
int a[MAXM],b[MAXN],f[MAXM],allb[MAXM],alla[MAXN];
int n,m,all,l,r,mid,ans,waste,need;
int read()
{
int f=1,x=0;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
bool dfs(int k,int start)
{
if (!k) return 1;
if (waste+need>all) return 0;
for (int i=start;i<=m;i++)
if (f[i]>=b[k])
{
f[i]-=b[k];
if (f[i]<b[1]) waste+=f[i];
if (b[k]==b[k-1])
{
if (dfs(k-1,i)) return 1;
}
else if (dfs(k-1,1)) return 1;
if (f[i]<b[1]) waste-=f[i];
f[i]+=b[k];
}
return 0;
}
bool ok(int p)
{
waste=0;
for (int i=1;i<=m;i++) f[i]=a[i];
need=allb[p];
return dfs(p,1);
}
void solve()
{
l=1,r=n,mid,ans;
while (l<=r)
{
mid=(l+r)>>1;
if (ok(mid)==1) l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d",ans);
}
int main()
{
m=read();
for (int i=1;i<=m;i++) a[i]=read();
n=read();
for (int i=1;i<=n;i++) b[i]=read();
sort(a+1,a+m+1);sort(b+1,b+n+1);
all=0;for (int i=1;i<=m;i++) all=all+a[i];
allb[0]=0;for (int i=1;i<=n;i++) allb[i]=allb[i-1]+b[i];
solve();
return 0;
}
难点是如何不超时。
解决这个问题我用了一些奇技淫巧,当然好多都是借鉴大神们的解法。
1.if (waste+need>all) return 0;
2. if (b[k]==b[k-1])
{
if (dfs(k-1,i)) return 1;
}
最后发现还是超时,然后去掉了几个头文件就过了......
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1111;
const int MAXM=55;
int a[MAXM],b[MAXN],f[MAXM],allb[MAXM],alla[MAXN];
int n,m,all,l,r,mid,ans,waste,need;
int read()
{
int f=1,x=0;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
bool dfs(int k,int start)
{
if (!k) return 1;
if (waste+need>all) return 0;
for (int i=start;i<=m;i++)
if (f[i]>=b[k])
{
f[i]-=b[k];
if (f[i]<b[1]) waste+=f[i];
if (b[k]==b[k-1])
{
if (dfs(k-1,i)) return 1;
}
else if (dfs(k-1,1)) return 1;
if (f[i]<b[1]) waste-=f[i];
f[i]+=b[k];
}
return 0;
}
bool ok(int p)
{
waste=0;
for (int i=1;i<=m;i++) f[i]=a[i];
need=allb[p];
return dfs(p,1);
}
void solve()
{
l=1,r=n,mid,ans;
while (l<=r)
{
mid=(l+r)>>1;
if (ok(mid)==1) l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d",ans);
}
int main()
{
m=read();
for (int i=1;i<=m;i++) a[i]=read();
n=read();
for (int i=1;i<=n;i++) b[i]=read();
sort(a+1,a+m+1);sort(b+1,b+n+1);
all=0;for (int i=1;i<=m;i++) all=all+a[i];
allb[0]=0;for (int i=1;i<=n;i++) allb[i]=allb[i-1]+b[i];
solve();
return 0;
}
相关文章推荐
- 【bzoj1082】 SCOI2005—栅栏
- 【BZOJ】1082: [SCOI2005]栅栏(二分+dfs)
- bzoj1082 [SCOI2005]栅栏
- [BZOJ 1082] [SCOI2005] 栅栏 【二分 + DFS验证(有效剪枝)】
- BZOJ 1082 [SCOI2005]栅栏 二分+DFS
- 【BZOJ1082】【SCOI2005】栅栏
- 【bzoj1082】[SCOI2005]栅栏
- BZOJ 1082 【SCOI2005】 栅栏
- BZOJ1082: [SCOI2005]栅栏
- BZOJ1082 [SCOI2005]栅栏
- [bzoj] 1082: [SCOI2005]栅栏
- BZOJ1082: [SCOI2005]栅栏
- bzoj1082[SCOI2005]栅栏
- BZOJ 1082 SCOI 2005 栅栏 搜索+剪枝
- [BZOJ1082][SCOI2005]栅栏
- bzoj1082: [SCOI2005]栅栏
- 【BZOJ 1082】[SCOI2005]栅栏 二分+dfs
- bzoj1082[SCOI2005]栅栏
- bzoj 1082: [SCOI2005]栅栏【二分+dfs】
- 【bzoj1082】 SCOI2005 栅栏 二分+搜索