染色dp(确定一行就可行)

题:https://codeforces.com/contest/1027/problem/E

题意:给定n*n的方格,可以染黑白,要求相邻俩行”完全“不同或完全相同,对于列也是一样。然后限制不能拥有k面积具有相同颜色的格子

分析:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e3+3;
const int mod=     998244353;
ll dp[M][M];///前i个存在最多连续j个相同的格子颜色 
void init(){
    dp[1][1]=1ll;
    dp[0][1]=1ll;
    for(int i=2;i<=500;i++){
        dp[i][i]=dp[i-1][i-1]*2ll%mod;///因为[i][i]就相当于没限制 ,所以直接每个位置俩个选择
        dp[0][i]=1ll; 
    } 
    for(int i=1;i<=500;i++){
        for(int j=1;j<=i;j++){
            dp[j][i]=dp[j][j];///不受限制的部分 
        }
        ///当前的j位置,可以选择与前一个位置相同,也可以选择与后一个相同
        ///若选择不相同,那么就在这个位置的贡献加上前一个位置的dp值
        ///若选择相同,那么就把这个位置和前一个位置看出一整体,然后重复上述动作; 
        for(int j=i+1;j<=500;j++)
            dp[j][i]=(2ll*dp[j-1][i]%mod-dp[j-i-1][i]+mod)%mod;
        
    }
} 
int main(){
    init();
    int n,k;
    cin>>n>>k;
    ll ans=0;
    for(int i=1;i<=n;i++){
        ll temp=dp[n][i]-dp[n][i-1];
        temp=temp*(dp[n][min((k-1)/i,n)])%mod;
        ans=(ans+temp)%mod;
    }
    ans*=2;
    cout<<ans%mod<<endl;
    return 0;
}
View Code

题:https://codeforces.com/contest/1248/problem/C

题意:黑白染色,限制:每个单元格最多具有一个相同颜色的相邻单元格

分析:确定了一行一列就可定下整个图

   考虑dp[i][0]为第i个填白色的方案数 所以易得:dp[i][0]=dp[i-2][0]+dp[i-1][1]

   考虑dp[i][1]为第i个填黑色的方案数 所以易得:dp[i][1]=dp[i-2][1]+dp[i-1][0]

   直接合并:dp[i]=dp[i-1]+dp[i-2];

#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
const int M=1e5+5;
const int mod=1e9+7;
ll f[M];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    f[1]=2;
    f[2]=4;
    fo(i,3,max(n,m))
        f[i]=(f[i-1]+f[i-2])%mod;
    printf("%I64d",((f[n]+f[m])%mod-2+mod)%mod);///又因为当行和列拼在一起时会导致格子(1,1),(1,2),(2,1) 三个格子同色,所以我们的答案是f(N)+f(M)−2。

    return 0;
} 
View Code

 

 

   

posted @ 2019-11-11 12:52  starve_to_death  阅读(180)  评论(0编辑  收藏  举报