MnZn 求助状压
查看原帖
MnZn 求助状压
420129
Nt_Tsumiki楼主2024/7/17 09:24

rt

同一个思路,一个填表,一个刷表,但是填表的 code 在 #73 比答案大了。

#include <iostream>
#include <cstdio>
#include <string>

#define MOD 1000000007
#define LL long long

using namespace std;
int n; string s;
LL dp[76][1<<19];

int cut(int l,int r) {
    int res=0;
    for (int i=l;i<=r;i++) res=res*2+s[i]-'0';
    return res;
}

int main() {
    scanf("%d",&n); cin>>s; s=" "+s;
    dp[0][0]=1;
    for (int i=1;i<=n;i++) {
        dp[i][0]=1;
        for (int j=i-1;j>=0;j--) {
            int val=cut(j+1,i);
            if (val>19) break;
            if (val) for (int k=0;k<(1<<19);k++)
                if ((k>>(val-1))&1) (dp[i][k]+=dp[j][k]+dp[j][k^(1<<(val-1))])%=MOD;
        }
    }
    LL ans=0;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=19;j++) (ans+=dp[i][(1<<j)-1])%=MOD;
    printf("%lld\n",ans);
    return 0;
}
#include <iostream>
#include <cstdio>
#include <string>

#define MOD 1000000007
#define LL long long

using namespace std;
int n; string s;
LL dp[76][1<<19];

int cut(int l,int r) {
    int res=0;
    for (int i=l;i<=r;i++) res=res*2+s[i]-'0';
    return res;
}

int main() {
    scanf("%d",&n); cin>>s; s=" "+s; 
    for (int i=0;i<=n;i++) {
        dp[i][0]++;
        for (int k=0;k<(1<<19);k++) 
            if (dp[i][k]) for (int j=i+1;j<=n;j++) {
                int val=cut(i+1,j);
                if (val>19) break;
                if (val) (dp[j][k|(1<<(val-1))]+=dp[i][k])%=MOD;
            }
    }
    LL ans=0;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=19;j++) (ans+=dp[i][(1<<j)-1])%=MOD;
    printf("%lld\n",ans);
    return 0;
}
2024/7/17 09:24
加载中...