萌新刚学oi0.01ms,两种写法为什么一样?
查看原帖
萌新刚学oi0.01ms,两种写法为什么一样?
891956
TempestMiku楼主2023/6/29 10:31
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace Testify{
    inline int read(){
        int f(1),x(0);
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    inline void Write(int x){
        if(x>9) Write(x/10);
        putchar(x%10+'0');
    }
    inline void write(int x){
        if(x<0) putchar('-'),x=-x;
        Write(x);
        putchar('\n');
    }
}
using namespace Testify;
const int N=12;
const int M=(1<<9);
int n,m,pic[N],dp[N][M][114],num[M],ok[M],cnt(0);
inline bool check1(int k){
    int a=(k<<1),b=(k>>1);
    if((a&k)||(b&k)) return false;
    return true;
}
inline bool check2(int shang,int xia){
    if(shang&xia) return false;
    if(shang&(xia<<1)) return false;
    if(shang&(xia>>1)) return false;
    return true;
}
//inline void er(int num){int arr[50],tmp,i=0;do{tmp=num%2;num=num/2; arr[i++]=tmp;} while (num);for(register int j=i-1;j>=0;j--){ Write(arr[j]);} puts("");}
signed main(void){
    n=read(),m=read();
    int inf=(1<<n)-1;
    num[0]=n;
    for(register int i=0;i<=inf;i++){
        if(check1(i)){
            cnt++;
            ok[cnt]=i;//记录可以的状态
            num[cnt]=__builtin_popcount(i);//记录当前状态有几个国王
        }
    }
    // dp[0][0][0]=1;
    for(register int i=1;i<=cnt;i++){//预处理第一行
        if(num[i]>m) continue;
        dp[1][ok[i]][num[i]]=1;
    }
    for(register int i=2;i<=n;i++){//第i行
        for(register int k=1;k<=cnt;k++){//第i行第k种状况
            for(register int y=1;y<=cnt;y++){//第i-1行第y种状况(上一行)
                if(!check2(ok[y],ok[k])){
                    continue;
                }
                for(register int op=1;op<=m;op++){
                    if(op+num[k]>m) break;
                    dp[i][ok[k]][op+num[k]]+=dp[(i-1)][ok[y]][op];
                }
                
            }
        }
    }
    int Arcaea(0);
    // for(register int i=1;i<=n;i++){
    //     for(register int j=1;j<=cnt;j++){
    //         cout<<dp[i][ok[j]][m]<<" ";
    //     }
    //     puts("");
    // }
    for(register int i=1;i<=n;i++){
        for(register int j=1;j<=cnt;j++){
            Arcaea+=dp[i][ok[j]][m];
        }
    }   
    write(Arcaea);
    return 0;
}

这个op从1开始循坏,最后累加的循坏有两层 可以AC

#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace Testify{
    inline int read(){
        int f(1),x(0);
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    inline void Write(int x){
        if(x>9) Write(x/10);
        putchar(x%10+'0');
    }
    inline void write(int x){
        if(x<0) putchar('-'),x=-x;
        Write(x);
        putchar('\n');
    }
}
using namespace Testify;
const int N=12;
const int M=(1<<9);
int n,m,pic[N],dp[N][M][114],num[M],ok[M],cnt(0);
inline bool check1(int k){
    int a=(k<<1),b=(k>>1);
    if((a&k)||(b&k)) return false;
    return true;
}
inline bool check2(int shang,int xia){
    if(shang&xia) return false;
    if(shang&(xia<<1)) return false;
    if(shang&(xia>>1)) return false;
    return true;
}
//inline void er(int num){int arr[50],tmp,i=0;do{tmp=num%2;num=num/2; arr[i++]=tmp;} while (num);for(register int j=i-1;j>=0;j--){ Write(arr[j]);} puts("");}
signed main(void){
    n=read(),m=read();
    int inf=(1<<n)-1;
    num[0]=n;
    for(register int i=0;i<=inf;i++){
        if(check1(i)){
            cnt++;
            ok[cnt]=i;//记录可以的状态
            num[cnt]=__builtin_popcount(i);//记录当前状态有几个国王
        }
    }
    // dp[0][0][0]=1;
    for(register int i=1;i<=cnt;i++){//预处理第一行
        if(num[i]>m) continue;
        dp[1][ok[i]][num[i]]=1;
    }
    for(register int i=2;i<=n;i++){//第i行
        for(register int k=1;k<=cnt;k++){//第i行第k种状况
            for(register int y=1;y<=cnt;y++){//第i-1行第y种状况(上一行)
                if(!check2(ok[y],ok[k])){
                    continue;
                }
                for(register int op=0;op<=m;op++){
                    if(op+num[k]>m) break;
                    dp[i][ok[k]][op+num[k]]+=dp[(i-1)][ok[y]][op];
                }
                
            }
        }
    }
    int Arcaea(0);
    // for(register int i=1;i<=n;i++){
    //     for(register int j=1;j<=cnt;j++){
    //         cout<<dp[i][ok[j]][m]<<" ";
    //     }
    //     puts("");
    // }
    for(register int i=n;i<=n;i++){
        for(register int j=1;j<=cnt;j++){
            Arcaea+=dp[i][ok[j]][m];
        }
    }   
    write(Arcaea);
    return 0;
}

这个op从0开始循坏,最后累加的循坏有1层 也可以ACAC

为什么????😭😭😭

2023/6/29 10:31
加载中...