状态压缩DP
复杂度为 2 n 2^n 2n,适用于 n ≤ 30 n\le30 n≤30
并查集
- 一定要初始化!!!
fa[i]=i;
- 作为要传给函数的变量,一定不要在循环里定义
(至于为什么我真不知道TAT)
10 p t s → 100 p t s 10pts→100pts 10pts→100pts
信息传递
#include <bits/stdc++.h>
using namespace std;
int f[200020],d[200020];
int minn;
int getfa(int x){
if(f[x]!=x){
int last=f[x];f[x]=getfa(f[x]);
d[x]+=d[last];
}
return f[x];
}
void check(int a,int b){
int x=getfa(a),y=getfa(b);
if(x!=y){
f[x]=y;d[a]=d[b]+1;
}
else{
minn=min(d[a]+d[b]+1,minn);
}
return;
}
int main(){
int n,t,i;
minn=0x3f3f3f3f;
scanf("%d",&n);
for(i=1;i<=n;++i){
f[i]=i;
}
for(i=1;i<=n;i++){//就是这里!!!
scanf("%d",&t);
check(i,t);
}
printf("%d",minn);
return 0;
}
二分答案
跳石头
注意
- l e le le, l l l变量名不要定义混乱
- 每一个变量名都有用
废话可是不知道为什么我一开始完全没考虑m瓜的 - 边界条件的处理
#include <bits/stdc++.h>
#define int long long
using namespace std;
int l,n,m,d[500050];
bool ok(int x){
int i=0;
int now=0,tot=0;
while(i<n+1){
i++;
if(d[i]-d[now]<x){
tot++;
}
else{
now=i;
}
}
if(tot>m){
return 0;
}
else{
return 1;
}
}
signed main(){
scanf("%lld%lld%lld",&l,&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&d[i]);
}
d[n+1]=l;
if(n==0){
printf("%lld",l);
return 0;
}
int le=1,r=l;
int mid,ans=0;
while(le<=r){
mid=(le+r)>>1;
if(ok(mid)){
ans=mid;
le=mid+1;
}
else{
r=mid-1;
}
}
printf("%lld",ans);
return 0;
}
字符串读入
P3952 时间复杂度
字符串读入建议输出读的东西,可能莫名读了一个空格
#include <bits/stdc++.h>
using namespace std;
const int maxl=105;
int t,l,w;
string o;
string code[maxl];
int sread(int &x,string c){//x传址,每次值都会相应改变,不需要初始化
int res=0;
int len=c.size();
while(c[x]<'0'||c[x]>'9'&&x<c.size()){
if(c[x]=='n'){
++x;return 1000000;
}
++x;
}
while(c[x]>='0'&&c[x]<='9'){
res=(res<<3)+(res<<1)+(c[x]^48);
++x;
}
return res;
}
int geto(){
int res=0,x=3;
int len=o.size();
if(o[2]=='n')res=sread(x,o);
else res=0;
return res;
}
int check(){
int res=0,now=0;
int a,b,x;
stack<int> s;
int flag=-1;
bool ins[26]={0};
bool ef[26]={0};
for(int i=1;i<=l;i++){
if(code[i][0]=='F'){
int k=code[i][2]-'a';
if(ins[k]) return -1;
s.push(k);ins[k]=true;
x=4;
a=sread(x,code[i]);b=sread(x,code[i]);//处理a的x与处理b的x值不一样
if(b-a>1000){
if(flag==-1){
now++;
res=max(res,now);
ef[k]=true;
}
}
if(a>b){
if(flag==-1)flag=k;
}
}
if(code[i][0]=='E'){
if(s.empty()) return -1;
int k=s.top();
s.pop();ins[k]=false;
if(flag==k) flag=-1;
if(ef[k]){
ef[k]=false;
now--;
}
}
}
if(s.size()) return -1;
return res;
}
int main(){
scanf("%d",&t);
while(t--){
int ww;
scanf("%d ",&l);getline(cin,o);//scanf里%d后一定要加空格
//不加是错的!!!!!加空格啊啊啊啊
w=geto();
for(int i=1;i<=l;i++){
getline(cin,code[i]);
}
ww=check();
if(ww==-1)puts("ERR");
else{
if(ww==w)puts("Yes");
else puts("No");
}
}
return 0;
}