练习3333

B - Charm Bracelet

01背包,不知道为什么没过

C - Sliding Window

数据结构,单调队列,线段树
try1:区间dp,这和枚举几乎无差

#include<iostream>
using namespace std;

void  solu(){

da[i][i]=a[i];

for(int len=1;len<=maxlen;len++){
    for(int i=1;i+len-1<=n;i++){
        int j=i+len-1;
        for(int k=i;k<=j;k++){
            da[i][j]=max(da[i][j],max(da[i][k],da[k+1][j]));
        }
    }
}


}

又尝试了一遍,分析确实枚举->dp复杂度降低,complite error
开不到这么大的数组

#include<iostream>
#define ll long long
using namespace std;
#define INF 0x3f3f3f3f
ll n,chuangz;
ll dp1[1000000][1000000];
ll dp2[1000000][1000000];


void solu(){
//n^2->nlogn



for(ll len=2;len<=chuangz;len++)
for(ll i=1;i+len-1<=n;i++){
    ll j=i+len-1;
    for(ll k=i;k<=j-1;k++){
        dp1[i][j]=min(dp1[i][j],min(dp1[i][k],dp1[k+1][j]));
        dp2[i][j]=max(dp2[i][j],max(dp2[i][k],dp2[k+1][j]));

    }
}

cout<<endl;
for(ll i=chuangz;i<=n;i++){

    cout<<dp1[i-chuangz+1][i];
    if(i!=n)cout<<" ";
}
cout<<endl;
for(ll i=chuangz;i<=n;i++){

    cout<<dp2[i-chuangz+1][i];
    if(i!=n)cout<<" ";
}

}

int main(){

cin>>n>>chuangz;

for(ll i=1;i<=n;i++)
for(ll j=i+1;j<=n;j++){
    dp1[i][j]=INF;dp2[i][j]=-INF;
}

for(ll i=1;i<=n;i++){cin>>dp1[i][i];dp2[i][i]=dp1[i][i];}

solu();
}

D - 摆花

P1077 [NOIP2012 普及组] 摆花

E - 飞扬的小鸟

状压dp,写了一半,思路简单,看出即使蹭天花板,最后不能过关的答案也不变
但有没有管子写起来好几种情况,也可以写,不值,算了

F - 消防局的设立

树形dp

G - 随机数生成器

期望dp

H - 互不侵犯

#include<iostream>
#define ll long long
using namespace std;
ll n,s;
ll maxn;
ll dp[10][1025][101];
ll num[1025];
void solu(){
for(ll j=0;j<maxn;j++)
dp[1][j][num[j]]=1;

for(ll i=2;i<=n;i++){
    for(ll j=0;j<maxn;j++){
        if(j&(j<<1))continue;
        for(ll k=0;k<maxn;k++){
            if(k&(k<<1))continue;
            if((k&j)||(k&(j<<1))||(j&(k<<1)))continue;
            for(ll cnt=num[j];cnt<=s;cnt++)
            dp[i][j][cnt]+=dp[i-1][k][cnt-num[j]];
                //这里空间太多,没有滚动,正序也对


        }
    }

}
ll ans=0;

for(ll j=0;j<maxn;j++){
ans+=dp[n][j][s];



}
cout<<ans;
}
ll get_sum(ll x){
    ll sum=0;
while(x){
sum+=(x&1);
x>>=1;
}

return sum;
}

int main(){

cin>>n>>s;
maxn=1<<n;
for(ll i=0;i<maxn;i++){

num[i]=get_sum(i);
}

solu();

}

I - Round Numbers

数位dp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值