DP(线性专题四)

23 篇文章 0 订阅
4 篇文章 0 订阅

题意 :一个圆环,每个位置可以选择 2 k 2^k 2k中任意一个数,要求相邻位置异或不等于 2 k − 1 2^k -1 2k1

>> face <<

Strategy:DP

状态: (本来没考虑头尾完全想法的情况疯狂wa)

d p [ i ] [ 0 ] : 头 和 尾 不 完 全 相 同 , 不 完 全 相 反 d p [ i ] [ 1 ] : 头 和 尾 完 全 相 同 d p [ i ] [ 2 ] : 头 和 尾 完 全 相 反 dp[i][0]:头和尾不完全相同,不完全相反 \\ dp[i][1]:头和尾完全相同\\ dp[i][2]:头和尾完全相反 dp[i][0]:,dp[i][1]:dp[i][2]:

边界: dp[1][1] = m, 一定注意边界条件一定要 从开头来推

转移:

{ d p [ i ] [ 0 ] = ( d p [ i − 1 ] [ 0 ] ∗ ( m − 3 ) + d p [ i − 1 ] [ 1 ] ∗ ( m − 2 ) + d p [ i − 1 ] [ 2 ] ∗ ( m − 2 ) ) % m o d , d p [ i ] [ 1 ] = ( d p [ i − 1 ] [ 1 ] + d p [ i − 1 ] [ 0 ] ) % m o d , d p [ i ] [ 2 ] = ( d [ i − 1 ] [ 2 ] + d p [ i − 1 ] [ 0 ] ) % m o d , \begin{dcases}dp[i][0] = (dp[i-1][0]*(m - 3) + dp[i -1][1]*(m - 2) + dp[i - 1][2]*(m - 2)) \%mod,\\ dp[i][1] = (dp[i-1][1] + dp[i - 1][0])\%mod,\\ dp[i][2] = (d[i-1][2] + dp[i - 1][0])\%mod, \end{dcases} dp[i][0]=(dp[i1][0](m3)+dp[i1][1](m2)+dp[i1][2](m2))%mod,dp[i][1]=(dp[i1][1]+dp[i1][0])%mod,dp[i][2]=(d[i1][2]+dp[i1][0])%mod,

attention: 边界要从1开始, 状态还是要缜密

#include <bits/stdc++.h>
#include <bits/extc++.h>
#define oo 0x3f3f3f3f
#define ll long long
#define db double
#define all(a) a.begin(), a.end()
#define met(a, b) memset(a, b, sizeof(a))
#define what_is(x) cout << #x << " is " << x << endl
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for (int i = (a); i >= (b); --i)
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define lowbit(x) x &(-x)
#define bin(x) cout << #x << " is " << bitset<sizeof(int) * 2>(x) << endl
#define pi acos(-1.0)
using namespace std;
using namespace __gnu_pbds;
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
const db eps = 1e-8;
vector<ll> pow2(maxn);
ll dp[maxn][3];
int main()
{
	pow2[0] = 1;
	_for(i, 1, maxn)
	{
		pow2[i] = pow2[i - 1] * 2 % mod;
		//what_is(pow2[i]);
	}
	int t;
	cin >> t;
	while (t--)
	{
		int n, k;
		cin >> n >> k;
		met(dp, 0);
		ll m = pow2[k];
		
		dp[1][1] = m;
		
		_rep(i, 2, n)
		{
			dp[i][1] = (dp[i - 1][1] + dp[i - 1][0]) % mod;
			dp[i][2] = (dp[i - 1][2] + dp[i - 1][0]) % mod;
			dp[i][0] = ((dp[i - 1][2] + dp[i - 1][1]) * (m - 2) + dp[i - 1][0] * (m - 3)) % mod;
		}
		cout << (dp[n][1 ] + dp[n][0]) % mod << endl;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值