求教:为什么这么写时间复杂度正确
查看原帖
求教:为什么这么写时间复杂度正确
246316
yanzihe楼主2024/7/19 08:51

如题,我的代码的时间复杂度是O(nk^2)的,却通过了这道题,题解里的时间复杂度分析我没有看懂。谁能教教我

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+9, MOD=1e9+7;
ll n, k;
ll sz[N];
vector <ll> to[N];
int f[N][109][2][2];//f[i][j][0/1][0/1]以i为根的子树,在其中部署j个监听器,i本身有没有部署监听器械,i本身有没有被监听
ll nf[109][2][2];
void dfs(ll u, ll fa){
    sz[u]=1;
    f[u][0][0][0]=f[u][1][1][0]=1;
    for(ll i=0;i<to[u].size();i++){
        ll v=to[u][i];
        if(v==fa)continue;
        dfs(v, u);
        sz[u]+=sz[v];
        fill(&nf[0][0][0], &nf[107][1][1], 0);
        for(ll j=0;j<=min(sz[u], k);j++){
            for(ll p1=0;p1<=1;p1++){
                for(ll q2=0;q2<=1;q2++)if(p1|q2){
                    for(ll q1=0;q1<=1;q1++){
                        for(ll l=0;l<=min(sz[v], j);l++){
                            for(ll p2=0;p2<=1;p2++){
                            
                                //现在将f[u][j-l][p1][q1]和f[v][l][p2][q2]进行整合
                                //得到了f[u][j][p1][q1|p2]
                                //这玩儿将加上f[u][j-l][p1][q1]*f[v][l][p2][q2]
                                //前提是p1|q2为1
                                
                                    (nf[j][p1][q1|p2]+=(ll)f[u][j-l][p1][q1]*(ll)f[v][l][p2][q2])%=MOD;
                                    // cout << "fs";
                                    // if(nf[j][p1][q1|p2]){
                                    // }
                                }
                            
                        }
                    }
                }
            }
        }
        for(ll j=0;j<=min(sz[u], k);j++){
            for(ll p1=0;p1<=1;p1++){
                for(ll q1=0;q1<=1;q1++){
                    f[u][j][p1][q1]=nf[j][p1][q1];
                    // cout << u << ' ' << j << ' ' << p1 <<' ' << q1<< ' ' << f[u][j][p1][q1] << endl;
                }
            }
        }
    }
}
ll degree[N];
int main(){
    // freopen("JSOI.in", "r", stdin);
    ios::sync_with_stdio(false);
    cin >> n >> k;
    for(ll i=1;i<n;i++){
        ll u, v;cin >> u >> v;
        to[u].push_back(v);
        to[v].push_back(u);
        degree[u]++;
        degree[v]++;
    }
    ll cnt=0;
    for(ll i=1;i<=n;i++){
        if(degree[i]>1)cnt++;
    }
    if(cnt>k*2){
        cout << 0 << endl;
        return 0;
    }
    dfs(1, 0);
    cout << (f[1][k][0][1]+f[1][k][1][1])%MOD << endl;
    return 0;
}
2024/7/19 08:51
加载中...