加载中…

返回上一页

NOIP模拟3

原 A层联测28 请走 CSP-S 模拟 10、13

下发文件

三元

一个简单的构造. 让最大的尽可能小,那就一定是形如 2 + 0...0 + 1/2...1/2 样子的数. 那就对应去构造这样的数,每一种一共有 n 个,那么就是一个三进制加法,从 2000...00 往上加即可.

直接加不优秀,那么就可以对它进行构造. 直接将每一相同数位的后面不断分裂. 然后类似地其他数也这么构造,注意别多了就行.

点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define rll rg ll
#define pll pair<ll,ll>
#define maxn 50001
#define ld long double
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,L,mx;
short ans[3][maxn][16];
int main()
{
	freopen("three.in","r",stdin); freopen("three.out","w",stdout);
	n=read();L=read()-1;mx=L-__builtin_ceill(__builtin_log2l(n)/__builtin_log2l(3));
	// cout<<n<<' '<<L<<' '<<mx<<endl;
	// for(rll i=1;i<=mx;i++) for(rll j=1;j<=n;j++) ans[2][j][i]=0;
	// assert(!ans[2][10][1]);
	for(rll i=mx+1,t=__builtin_powl(3,L-mx-1);i<=L;i++,t/=3)
	{
		for(rll j=0;j<n;j++) /*cout<<i<<' '<<j<<endl,*/ans[2][j+1][i]=(j/t)%3;
		// cout<<t<<endl;write(i);putn;assert(!ans[2][10][1]);
	}
	for(rll i=1;i<=mx;i++) for(rll j=1;j<=n;j++) ans[0][j][i]=2;
	for(rll i=mx+1,t=__builtin_powl(3,L-mx-1);i<=L;i++,t/=3) for(rll j=0;j<n;j++) ans[0][j+1][i]=(j/t+2)%3;
	for(rll i=1;i<=mx;i++) for(rll j=1;j<=n;j++) ans[1][j][i]=1;
	for(rll i=mx+1,t=__builtin_powl(3,L-mx-1);i<=L;i++,t/=3) for(rll j=0;j<n;j++) ans[1][j+1][i]=(j/t+1)%3;
	// cout<<endl;assert(!ans[2][10][1]);
	for(rll i=0;i<3;i++) for(rll k=1;k<=n;k++) { write(i); for(rll j=1;j<=L;j++) write(ans[i][k][j]); putn; }
	return 0;
}

鹅国

看到这玩意就往 dp 上去想,准没错. 首先最简单的背包就不说了.

然后,可以设 dp[0/1][j][k] 表示已选中 j 个,当前这次选了 k 个的最小和最大的重量.

转移时,枚举每一个硬币和 jk,然后再枚举一层,用来表示当前这些硬币能否用更小的来替换,是否对答案有贡献. 有则转移取最值.

因为每一轮不能更改上一轮的状态,所以用一个滚动数组. 处理答案的时候为了方便多转移一次到 k + 1 处. 最后把整个答案和上一轮的答案与最小的那个硬币组合取一个最值(其实是可以放到转移里面的...).

不是正解,但是 n × k3 足以通过本题.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define pll pair<ll,ll>
#define maxn 1001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,k,p,c[maxn],w[maxn],dp[2][2][maxn][maxn],mo,ans1,ans2;
bool pp;
int main()
{
	freopen("goose.in","r",stdin); freopen("goose.out","w",stdout);
	n=read();k=read();p=read(); for(rll i=1;i<=n;i++) c[i]=read(),w[i]=read();
	// cout<<p<<' '<<c[1]<<endl;
	assert(c[1]);
	if((p%c[1])||p/c[1]<k||p/c[n]>k) { puts("-1");return 0; } p/=c[1]; for(rll i=n;i;i--) c[i]/=c[1];
	memset(dp[1][0],0b00111111,sizeof(dp[1][0])); memset(dp[1][1],0b11000000,sizeof(dp[1][1]));
	assert(c[n]);
	dp[1][0][p/c[n]][p/c[n]]=dp[1][1][p/c[n]][p/c[n]]=0;
	for(rll i=n;i;i--)
	{
		memset(dp[pp][0],0b00111111,sizeof(dp[pp][0])); memset(dp[pp][1],0b11000000,sizeof(dp[pp][1])); mo=p%c[i];
		for(rll j=1,t;j<=k;j++) for(rll l=0;l<=k;l++) if(!(dp[pp^1][1][j][l]&LLONG_MIN)) for(rll m=0;m<=l;m++)
		{
			// cout<<i<<' '<<c[i]<<' '<<c[i-1]<<endl; assert(c[i-1]);
			if(i^1) t=(c[i]/c[i-1])*m+mo/c[i-1]; else t=0;
			if(t+j-m<=k) dp[pp][0][j-m+t][t]=min(dp[pp][0][j-m+t][t],dp[pp^1][0][j][l]+(l-m)*w[i]),
				dp[pp][1][j-m+t][t]=max(dp[pp][1][j-m+t][t],dp[pp^1][1][j][l]+(l-m)*w[i]);
		}
		pp^=1;
	}
	ans1=dp[pp^1][0][k+1][0],ans2=dp[pp^1][1][k+1][0];
	for(rll i=0;i<=k;i++) ans1=min(ans1,dp[pp^1][0][k][i]+w[1]*i),ans2=max(ans2,dp[pp^1][1][k][i]+w[1]*i);
	if(ans1==0b0011111100111111001111110011111100111111001111110011111100111111) { puts("-1"); return 0; }
	write(ans1);put_;write(ans2);putn;
	return 0;
}

楼盘

不会,没改.

矩形

先拿一个单调栈去求出每一个点它的高度所能延伸的最大值(就是找那个最大的矩形). 我就不写笛卡尔树,谁说单调栈是 n2

对于每一个排序后的高度,显然是单调的,因此可以进行二分. 把 LR 对应的数字二分出来,枚举所有的数字,查询其排名不断插入即可.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define pll pair<ll,ll>
#define maxn 300001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,h[maxn],l,r,posl,posr,mx,st[maxn],ed[maxn];
stack<ll> s;
vector<ll> ans;
#define S(x) ((x)<=0?0:(x)*((x)+1)>>1)
#define f(pos,l,r) (S(pos)-S((pos)-(l)-1)-S((pos)-(r)-1)+S((pos)-(l)-(r)-2))
inline bool chk(rll x,rll num)
{
	if(x-1<=0) return 1; rll ans=0; for(rll i=1;i<=n;i++) ans+=f(min((x-1)/h[i],ed[i]-st[i]+1),i-st[i],ed[i]-i); return ans<num;
}
inline ll erfen(rll x)
{ 
	rll l=0,r=1000000000000000000,ans=-1; while(l<=r) { rll mid=l+r>>1; if(chk(mid,x)) ans=mid,l=mid+1; else r=mid-1; } assert(~ans); return ans; 
}
int main()
{
	freopen("rectangle.in","r",stdin); freopen("rectangle.out","w",stdout);
	n=read(); for(rll i=1;i<=n;i++) h[i]=read(); l=read();r=read(); s.push(st[1]=1);
	for(rll i=2;i<=n;i++) { while((!s.empty())&&h[i]<h[s.top()]) ed[s.top()]=i-1,s.pop(); if(s.empty()) st[i]=1; else st[i]=s.top()+1; s.push(i); }
	while(!s.empty()) ed[s.top()]=n,s.pop(); posl=erfen(l),posr=erfen(r);// for(rll i=1;i<=n;i++) cout<<st[i]<<' '<<ed[i]<<endl; cout<<posl<<' '<<posr<<endl;
	rll t=0; for(rll i=1;i<=n;i++) t+=f(min(posl/h[i],ed[i]-st[i]+1),i-st[i],ed[i]-i); mx=min(t,r);
	for(rll i=l;i<=mx;i++) ans.emplace_back(posl);
	for(rll i=1,mx,mn,s,t,tot;i<=n;i++)
	{
		mx=max(ed[i]-i+1,i-st[i]+1),mn=min(ed[i]-i+1,i-st[i]+1),s=posl/h[i]+1,t=min(ed[i]-st[i]+1,(posr-1)/h[i]);
		for(rll j=s;j<=t;j++)
		{
			if(j<=mn) tot=j; else if(j<=mx) tot=mn; else tot=ed[i]-st[i]-j+2; while(tot--) ans.emplace_back(j*h[i]);
		}
	}
	while(ans.size()<r-l+1) ans.emplace_back(posr); sort(ans.begin(),ans.end()); for(rll i=0;i<ans.size();i++) write(ans[i]),put_;
	return 0;
}
posted @ 2022-11-15 20:17  1Liu  阅读(31)  评论(0编辑  收藏  举报