2013南京 Onsite 代码(未提交)

本文分享了一位参赛者在长时间未进行训练的情况下,如何在比赛中脱颖而出,通过解决C、E、K三个问题,最终获得第一名的经历。详细介绍了比赛中使用的技巧和策略,包括使用特定的头文件和函数库,以及在有限时间内高效完成任务的方法。
将近1年没好好训练,结果弄个4题第一名,将近1半比赛的时间都没碰过pc^2 比赛的时候看的C,E,K, 都敲出来, 有机会交下, 我真是个逗逼, 
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxr = 103;
const int maxc = 12;
int dp[103][12][2048+123][22];
char mp[maxr][maxc];
const int mod = 10e9+7;

int main(){
    freopen("c.in", "r", stdin);
    int N, M, C, D;
    while (~scanf("%d%d%d%d", &N, &M, &C, &D)){
        memset (dp, 0, sizeof(dp));
        for (int i=1; i<=N; ++i){
            scanf("%s", mp+i);
        }
        int lim = 1<<(M+1);/// 0 -> 
        dp[0][M][0][0] = 1;
        for (int i=1; i<=N; ++i){
            for (int k=0; (k<<1)<lim; ++k){
                for (int c=0; c<=D; ++c)
                    dp[i][0][k<<1][c] = dp[i-1][M][k][c];
            }
            
            for (int j=1; j<=M; ++j){
                const int ma = 1<<j;
                const int mb = 1<<(j-1);
                for (int k=0; k<lim; ++k){
                    if(mp[i][j-1] == '1'){
                        if(!(k&ma) && !(k&mb)){
                            for (int c=0; c<D; ++c){/// 00 -> 00  1*1 placed
                                dp[i][j][k][c+1] += dp[i][j-1][k][c];
                                dp[i][j][k][c+1] %= mod;
                            }
                            
                            for (int c=0; c<=D; ++c){/// 00 -> 01 or 10  non placed
                                dp[i][j][k|ma][c] += dp[i][j-1][k][c];
                                dp[i][j][k|ma][c] %= mod;
                                dp[i][j][k|mb][c] += dp[i][j-1][k][c];
                                dp[i][j][k|mb][c] %= mod;
                            }
                        }
                        if( (!(k&ma)) ^ (!(k&mb)) ) /// 01/10 -> 00 2*1 or 1*2 placed
                            for (int c=0; c<=D; ++c){
                                dp[i][j][k^(k&ma)^(k&mb)][c] += dp[i][j-1][k][c];
                                dp[i][j][k^(k&ma)^(k&mb)][c] %= mod;
                            }
                        /// 11 is invalid 
                    }
                    else {
                        if(!(k&ma) && !(k&mb)) /// 00 -> 00  forbid to place 
                            for (int c=0; c<=D; ++c){
                                dp[i][j][k][c] += dp[i][j-1][k][c];
                                dp[i][j][k][c] %= mod;
                            }
                    }
                }
            }
        }
        long long ans = 0;
        for (int i=C; i<=D; ++i){
            ans = (ans+dp[N][M][0][i])%mod;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值