11/13总结报告

这一周主要是先练了上周学的数位dp的模板,做了模板题熟悉几遍,然后就是看了状态dp的博客,不过说实话,这个状态dp挺难懂的,看了很长时间也不是很明白,而且这个状态dp用到很多位移运算符,虽说这样会让代码快很多,但是也导致在看某些题目的时候就会有的地方看不明白什么意思比较费劲,之前的数位dp是专门在数位上进行处理,这个状态dp当时看的时候有部分感觉有点像之前学的枚举里的子集枚举,就是用二进制来表示不同的状态,而二进制是可以代表一些很大的数的所以以此来进行状态的转移,

代表题目:

5.1、 USACO06NOV Corn Fields G


 

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 10 + 5,M = 10 + 5;
const int P = 1e8;

int n,m;
int a[N][M],st[N];
bool g[1 << N];
int f[N][1 << N];
void solve(){
}
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++ i){
        for(int j = 1; j <= m; ++ j){
            scanf("%d", &a[i][j]);
        }
    }
    
    for(int i = 1; i <= n; ++ i){
        for(int j = 1; j <= m; ++ j){
            st[i] = (st[i] << 1) + a[i][j];  
        }
    }
  
    int maxn = 1 << m;
    f[0][0] = 1;
    for(int i = 0; i < maxn; ++ i){
        g[i] = !( i & (i << 1));  
    }
    for(int i = 1; i <= n; ++ i){
        
        for(int j = 0; j < maxn; ++ j){
         
            if(g[j] && (j & st[i]) == j){///
               
                for(int k = 0; k < maxn; ++ k){  ///
                    if(!(j & k)){  
                        f[i][j] = (f[i][j] + f[i - 1][k]) % P;
                    }
                }
            }
        }
    }
    int ans = 0;
    for(int j = 0; j < maxn; ++ j){
        ans = (ans + f[n][j]) % P;
    }
    printf("%d\n", ans);
    solve();
    return 0;
}

这道题题目简单容易理解,这个代码我感觉是相对容易理解的多的,而且还有许多位移运算符的几个小用法以及一些句子可以当技巧记住的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Assault boy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值