ABC415
被C卡了
不是为啥啊
C
题意:
判断是否能够通过状态转移使0转移到2^n-1
其中有些状态无法转移
思路:
这题要用dp。:(
dp[0]=1,如果状态可以被转移,那么按位判断
void solve(){
int n;cin>>n;
string s;cin>>s;
int m=s.size();
s=" "+s;
vector<int>vis(m+1);
vector<int>dp((1ll<<n)+1);
rep(i,1,m){
if(s[i]=='1')vis[i]=1;
}
dp[0]=1;
for(int i=1;i<(1ll<<n);i++){
if(vis[i])continue;
for(int j=0;j<n;j++){
if(i&(1ll<<j)){
if(dp[(i^(1ll<<j))])dp[i]=1;
}
}
}
if(dp[(1ll<<n)-1]){
cout<<"Yes"<<endl;
}else cout<<"No"<<endl;
}
E
题意:
给定一个矩阵,每次要么向下走要么向右走。每走一步,先拿矩阵值,再消耗px
求让每一步操作后值大小都不小于0的最小初始值
思路:
发现求的是从左上到右下中路径的谷值
可以使用反向dp。因为如果正向dp,初始值是待求不确定的
记dp[i][j]为从(i,j)->(n,m)所需的额外初值
为了使答案最小,最后操作后剩余值一定为0
因此反向dp初始值为0
每次操作相当于拿了px值,再消耗矩阵值
如果dp[i][j]<=0,意味着不需要消耗额外的初值。因为一开始钱不可能为负的,所以此时dp[i][j]=0
如果dp[i][j]>0,意味着需要消耗额外的初值。
考虑转移,显然dp[i][j]->dp[i][j-1],dp[i-1][j]
需要使dp[i][j-1],dp[i-1][j]尽可能小
答案为dp[1][1]
int n,m;
void solve(){
cin>>n>>m;
vector<vector<int>>g(n+1,vector<int>(m+1));rep(i,1,n)rep(j,1,m)cin>>g[i][j];
vector<vector<int>>f(n+1,vector<int>(m+1,1e18));
vector<int>p(n+m+1);rep(i,1,n+m-1)cin>>p[i];
f[n][m]=0;
for(int i=n;i>=1;i--){
for(int j=m;j>=1;j--){
f[i][j]+=p[i+j-1]-g[i][j];
f[i][j]=max(0ll,f[i][j]);
f[i-1][j]=min(f[i-1][j],f[i][j]);
f[i][j-1]=min(f[i][j-1],f[i][j]);
}
}
cout<<f[1][1]<<endl;
}
F
用线段树维护区间相同字符最大长度
struct SGT{
#define ls p<<1
#define rs p<<1|1
string s;
struct node{
int l,r;
int lv,rv;
int len,ans;
node():l(0),r(0),lv(0),rv(0),len(0),ans(0){}
}tr[maxn<<2];
void pushup(int p){
if(tr[ls].lv==tr[ls].len&&s[tr[ls].r]==s[tr[rs].l]){
tr[p].lv=tr[ls].len+tr[rs].lv;
}else tr[p].lv=tr[ls].lv;
if(tr[rs].rv==tr[rs].len&&s[tr[ls].r]==s[tr[rs].l]){
tr[p].rv=tr[rs].len+tr[ls].rv;
}else tr[p].rv=tr[rs].rv;
tr[p].ans=max(tr[ls].ans,tr[rs].ans);
if(s[tr[ls].r]==s[tr[rs].l]){
tr[p].ans=max(tr[p].ans,tr[ls].rv+tr[rs].lv);
}
tr[p].ans=max({tr[p].ans,tr[ls].lv,tr[rs].rv});
}
void build(int p,int l,int r){
tr[p].l=l;tr[p].r=r;tr[p].len=(r-l+1);
if(l==r){
tr[p].lv=tr[p].rv=tr[p].ans=1;return;
}
int mid=l+r>>1;
build(ls,l,mid);build(rs,mid+1,r);
pushup(p);
}
void add(int p,int pos,char ch){
if(tr[p].l==tr[p].r&&tr[p].l==pos){
s[pos]=ch;return;
}
int mid=tr[p].l+tr[p].r>>1;
if(pos<=mid)add(ls,pos,ch);
else add(rs,pos,ch);
pushup(p);
}
node query(int p,int l,int r){
if(l<=tr[p].l&&tr[p].r<=r)return tr[p];
int mid=tr[p].l+tr[p].r>>1;
if(r<=mid)return query(ls,l,r);
if(l>mid)return query(rs,l,r);
node L=query(ls,l,r);
node R=query(rs,l,r);
node res;
res.l=L.l;res.r=R.r;
res.len=L.len+R.len;
if(L.lv==L.len&&s[L.r]==s[R.l])res.lv=L.len+R.lv;
else res.lv=L.lv;
if(R.rv==R.len&&s[L.r]==s[R.l])res.rv=R.len+L.rv;
else res.rv=R.rv;
res.ans=max(L.ans,R.ans);
if(s[L.r]==s[R.l]){
res.ans=max(res.ans,L.rv+R.lv);
}
res.ans=max({res.ans,res.lv,res.rv});
return res;
}
}seg;
void solve(){
int n,m;cin>>n>>m;
string s;cin>>s;
s=" "+s;
seg.s=s;
seg.build(1,1,n);
while(m--){
int opt;cin>>opt;
if(opt==1){
int pos;char ch;cin>>pos>>ch;
seg.add(1,pos,ch);
}else{
int l,r;cin>>l>>r;
cout<<(seg.query(1,l,r).ans)<<endl;
}
}
}

浙公网安备 33010602011771号