【比赛】高一下二调2
下载题解
其实是一道水题,但容易想偏,如以为是逆序对
点击查看代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6;
int n,a[N+5],b[N+5],ans;
int main()
{
freopen("seat.in","r",stdin);
freopen("seat.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[a[i]]=i;
}
for(int i=1;i<=n;i++)
{
if(a[i]!=i)
{
int pos=b[i];
swap(a[i],a[pos]);
b[a[i]]=a[i];
b[a[pos]]=pos;
ans++;
}
}
cout<<ans;
return 0;
}
/*
8
5 4 2 3 6 8 7 1
*/
区间DP,也可以用记忆化搜索
区间DP
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6,mod=1e9;
ll f[305][305];
string s;ll n;
int main()
{
// freopen("school.in","r",stdin);
// freopen("school.out","w",stdout);
cin>>s;
s.insert(s.begin(),'*');//相当于s从一开始输入
n=s.size()-1;
// cout<<n;
for(int i=0;i<=n;i++)f[i][i]=1;
for(int len=3;len<=n;len++)
{
for(int l=1;l+len-1<=n;l++)
{
int r=l+len-1;
if(s[l]==s[r])
{
f[l][r]=f[l+1][r-1];
for(int k=l+2;k<=r-2;k++)
{
if(s[l]==s[k])//不知道为什么可加可不加
f[l][r]=(f[l][r]+f[l+1][k-1]*f[k][r])%mod;
// cout<<l<<" "<<r<<" "<<f[l][r]<<endl;
}
}
else
{
f[l][r]=0;//不成立
}
}
}
cout<<f[1][n];
return 0;
}
/*
BBAAABAAAAABABBBBBB
ABAAABA
ABABABA
ABCDCA
ABCDEFGHIJKLMNOPQRSTUVWXY/ABCDEFGHIJKLMNOPQRSTUVWXY/Z/YXWVUTSRQPONMLKJIHGFEDCBA/YXWVUTSRQPONMLKJIHGFEDCBA
A
*/
点击查看代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6,mod=1e9;
ll f[305][305];
string s;ll n;
ll dp(int l,int r)
{
// cout<<l<<" "<<r<<endl;
if(l>r)return 0;
if(l==r)return 1;
if(f[l][r]!=-1)return f[l][r];
f[l][r]=0;
for(int i=l+2;i<=r;i++)
{
if(s[l]==s[r])f[l][r]=(f[l][r]+(ll)dp(l+1,i-1)*dp(i,r)%mod)%mod;
// cout<<l<<" "<<r<<" "<<f[l][r]<<endl;
}
return f[l][r];
}
int main()
{
freopen("school.in","r",stdin);
freopen("school.out","w",stdout);
memset(f,-1,sizeof(f));
cin>>s;
n=s.size();
int zh=0;
// cout<<n;
dp(0,n-1);
cout<<f[0][n-1];
return 0;
}
/*
BBAAABAAAAABABBBBBB
ABAAABA
ABABABA
ABCDCA
ABCDEFGHIJKLMNOPQRSTUVWXY/ABCDEFGHIJKLMNOPQRSTUVWXY/Z/YXWVUTSRQPONMLKJIHGFEDCBA/YXWVUTSRQPONMLKJIHGFEDCBA
A
*/
类似糖果,差分约束
一些很容易遗漏的点,如图不一定联通,因为是有向的,所以必须建一个超级源点,但因为题目中说最少的舱室放置1单位的药炸
所以为add(0,i,1)而不是权值为0
还有,差分约束,求最小值,跑最长路,关系式为大于等于关系\(x_i-x_j>=c\),最后答案并不是dis[n],\(dis[i]\)表示就是单独i点权值,所以答案是1~n的和
注意判断无解情况
记得开LONGLONG
SPFA会T
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5,mod=1e9;
ll cnt,n,m,head[N+5],dis[N+5],in[N+5];bool vis[N+5];
struct e
{
ll from,to,next,w;
}edge[N*2+5];
void add(int u,int v,int w)
{
edge[++cnt].from=u;
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
bool spfa(int st)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
dis[i]=0;
in[i]=0;
}
dis[st]=0;vis[st]=1;
queue <int> q;
q.push(st);
while(!q.empty())
{
int u=q.front();q.pop();
vis[u]=0;
in[u]++;
// cout<<to<<" "<<in[to]<<endl;
if(in[u]>n)
{
return 0;
}
for(int i=head[u];i>=0;i=edge[i].next)
{
int to=edge[i].to;
if(dis[to]<dis[u]+edge[i].w)
{
dis[to]=dis[u]+edge[i].w;
// cout<<to<<" "<<dis[to]<<endl;
if(!vis[to])
{
q.push(to);vis[to]=1;
}
}
}
}
return 1;
}
int main()
{
// freopen("c.in","r",stdin);
freopen("bomb.in","r",stdin);
freopen("bomb.out","w",stdout);
memset(head,-1,sizeof(head));
scanf("%lld%lld",&n,&m);//min
ll t,a,b;
for(int i=1;i<=n;i++)add(0,i,1);
for(int i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&t,&a,&b);
if(t==1)
{
add(a,b,0);add(b,a,0);
}else if(t==2)
{
add(a,b,1);//a<b b-a>=1
if(a==b)
{
cout<<-1<<endl;
return 0;
}
}else if(t==3)
{
add(b,a,0);//a>=b
}else if(t==4)
{
add(b,a,1);//a>b
if(a==b)
{
cout<<-1<<endl;
return 0;
}
}else if(t==5)
{
add(a,b,0);//a<=b
}
}
if(!spfa(0))
{
cout<<-1<<endl;
return 0;
}
ll ans=0;
for(int i=1;i<=n;i++)
{
ans+=dis[i];
}
cout<<ans;
return 0;
}
/*
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
4 4
1 3 4
1 1 2
1 2 3
1 4 1
*/
Tarjan+拓扑
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5,mod=1e9;
ll cnt,n,m,head[N+5],head2[N+5],in[N+5],cnt2;bool vis[N+5];
struct e
{
ll from,to,next,w;
}edge[N*3+5],e2[N*3+5];
void add(int u,int v,int w)
{
edge[++cnt].from=u;
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
void add2(int u,int v,int w)
{
e2[++cnt2].from=u;
e2[cnt2].to=v;
e2[cnt2].w=w;
e2[cnt2].next=head2[u];
head2[u]=cnt2;
}
int dfn[N+5],low[N+5],dfscnt;
stack<int>stk;
int ge,belong[N+5],size[N+5];
void tarjan(int now)
{
dfn[now]=low[now]=++dfscnt;
stk.push(now);
vis[now]=1;
for(int i=head[now];i;i=edge[i].next)
{
int to=edge[i].to;
if(!dfn[to])
{
tarjan(to);
low[now]=min(low[now],low[to]);
}else if(vis[to])
{
low[now]=min(low[now],dfn[to]);
}
}
if(low[now]==dfn[now])
{
int y;
ge++;
do
{
y=stk.top();
stk.pop();
belong[y]=ge;
size[ge]++;
vis[y]=0;
}while(y!=now);
}
}
ll ans=0,dp[N+5];
void topsort()
{
// memset(dp,0x3f,sizeof(dp));
queue <int> q;
for(int i=1;i<=ge;i++)
if(!in[i])q.push(i);
while(!q.empty())
{
int u=q.front();q.pop();
for(int j=head2[u];j;j=e2[j].next)
{
int to=e2[j].to;
in[to]--;dp[to]=max(dp[to],dp[u]+e2[j].w);
// cout<<dp[to]<<endl;
if(!in[to])
{
ans+=dp[to]*size[to];
q.push(to);
// cout<<to<<" "<<dp[to]<<" "<<size[to]<<endl;
}
}
}
}
int main()
{
// freopen("c.in","r",stdin);
freopen("bomb.in","r",stdin);
freopen("bomb.out","w",stdout);
// memset(head,-1,sizeof(head));
scanf("%lld%lld",&n,&m);//min
ll t,a,b;
for(int i=1;i<=n;i++)add(0,i,1);
for(int i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&t,&a,&b);
if(t==1)
{
add(a,b,0);add(b,a,0);
}else if(t==2)
{
add(a,b,1);//a<b b-a>=1
if(a==b)
{
cout<<-1<<endl;
return 0;
}
}else if(t==3)
{
add(b,a,0);//a>=b
}else if(t==4)
{
add(b,a,1);//a>b
if(a==b)
{
cout<<-1<<endl;
return 0;
}
}else if(t==5)
{
add(a,b,0);//a<=b
}
}
for(int i=0;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
for(int i=1;i<=cnt;i++)
{
int from=edge[i].from,to=edge[i].to;
if(belong[from]!=belong[to])
{
// cout<<belong[from]<<" "<<belong[to]<<endl;
add2(belong[from],belong[to],edge[i].w);
in[belong[to]]++;
}else if(belong[from]==belong[to]&&edge[i].w==1)
{
cout<<-1<<endl;
return 0;
}
}
topsort();
cout<<ans;
return 0;
}
/*
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
4 4
1 3 4
1 1 2
1 2 3
1 4 1
*/
二分能过,记得优先队列栈顶为最大值,别用混变量名
注意判断无解情况
点击查看代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5,mod=1e9;
ll n,c,f;
struct ac
{
ll sco,m;
}a[N+5];
bool cmp(ac a,ac b)
{
return a.sco<b.sco;
}
bool check(ll mid)
{
int lf=(n-1)/2,lr=lf;
ll mm=a[mid].m;
priority_queue <ll,vector<ll>,greater<ll> > l,r;
for(int i=1;i<=mid-1;i++)
{
l.push(a[i].m);
}
while(!l.empty()&&lf)
{
mm+=l.top();
// cout<<"**"<<l.top()<<endl;
l.pop();
lf--;
}
if(mm>f)return 0;
for(int i=mid+1;i<=c;i++)
{
r.push(a[i].m);
}
while(!r.empty()&&lr)
{
mm+=r.top();
// cout<<r.top()<<endl;
r.pop();
lr--;
}
// cout<<mm;
if(mm<=f)return 1;
else return 0;
}
int ans=0;
void fen(ll l,ll r)
{
while(l<=r)
{
ll mid=(l+r)>>1;
if(check(mid))
{
l=mid+1;
ans=mid;
}else
{
r=mid-1;
}
}
if(!a[ans].sco)
{
cout<<-1<<endl;
}else
cout<<a[ans].sco<<endl;
exit(0);
}
int main()
{
// freopen("d.in","r",stdin);
freopen("money.in","r",stdin);
freopen("money.out","w",stdout);
// ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>c>>f;
for(int i=1;i<=c;i++)
{
cin>>a[i].sco>>a[i].m;
}
sort(a+1,a+1+c,cmp);
// fen((n+1)/2,c-(n-1)/2);
// cout<<a[10].sco<<endl;
fen((n+1)/2,c-(n-1)/2);
// for(int i=c-(n-1)/2;i>=(n+1)/2;i--)
// {
//// if(check(i))
//// {
//// cout<<a[i].sco<<endl;
//// return 0;
////// break;
//// }
// }
cout<<-1;
return 0;
}
/*
3 5 70
30 25
50 21
20 20
5 18
35 30
*/
点击查看代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5,mod=1e9;
ll n,c,f;
struct ac
{
ll sco,m;
}a[N+5];
bool cmp(ac a,ac b)
{
return a.sco<b.sco;
}
int ans=0;
ll sumf[N+5],sume[N+5];
int main()
{
// freopen("d.in","r",stdin);ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
freopen("money.in","r",stdin);
freopen("money.out","w",stdout);
cin>>n>>c>>f;
for(int i=1;i<=c;i++)
{
cin>>a[i].sco>>a[i].m;
}
sort(a+1,a+1+c,cmp);
int st=n/2;ll sum=0;
priority_queue <ll> l,r;//top is max
for(int i=1;i<=st;i++)
{
sum+=a[i].m;
l.push(a[i].m);
}
for(int i=st+1;i<=c-st;i++)
{
sumf[i]=sum;
l.push(a[i].m);
sum-=l.top();
sum+=a[i].m;
l.pop();
}
sum=0;
for(int i=c;i>=c-st+1;i--)
{
sum+=a[i].m;
r.push(a[i].m);
}
for(int i=c-st;i>=st+1;i--)
{
sume[i]=sum;
r.push(a[i].m);
sum-=r.top();
sum+=a[i].m;
r.pop();
}
ll ans=-1;
for(int i=st+1;i<=c-st;i++)
{
//// cout<<sumf[i]<<" "<<sume[i]<<" "<<a[i].m<<endl;
if(sumf[i]+sume[i]+a[i].m<=f)
{
ans=max(ans,a[i].sco);
}
}
cout<<ans;
return 0;
}
/*
3 5 70
30 25
50 21
20 20
5 18
35 30
*/
二分,被卡了,不具有单调性死了