题目链接:https://codeforces.com/problemset/problem/182/E
题目大意:有n个木板,每种类型木板有一个长x和宽y,如果同一个类型木板旋转后长x和宽y和之前一样,那么只能算做一个木板,否则可以算做同类型的不同木板。现在商店每种类型的木板有无数种。如果要搭建长度为l的篱笆。问有多少种方案。

必须满足:
1.连续的两块木板类型不能相同
2.除了第一块木板,后面的木板的长必须等于上一块木板的宽。

因为状态与最后一块木板有关系, 那么我们必须二维。
直接dp[i][j]:最后一块木板为j,搭长度为i的篱笆的方案数。
枚举上一块的篱笆k就可以转移了(k=0:上一块没有)。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int mod=1e9+7;

struct node{
    int x, y, k;
}a[205];
LL f[3005][205];

int main(){

    int n, l, tot=1;
    scanf("%d%d", &n, &l);
    for(int i=1; i<=n; i++){
        scanf("%d%d", &a[tot].x, &a[tot].y);
        a[tot].k=i;
        if(a[tot].x!=a[tot].y){
            tot++;
            a[tot].x=a[tot-1].y;
            a[tot].y=a[tot-1].x;
            a[tot].k=i;
        }
        tot++;
    }
    for(int i=1; i<=l; i++){
        for(int j=1; j<tot; j++){
            for(int k=0; k<tot; k++){
                if(a[j].k==a[k].k){
                    continue;
                }
                if(k==0&&a[j].x==i){
                    f[i][j]++;
                    f[i][j]%=mod;
                }
                else if(a[j].x==a[k].y&&i>a[j].x){
                    f[i][j]+=f[i-a[j].x][k];
                    f[i][j]%=mod;
                }
            }
        }
    }
    LL ans=0;
    for(int i=1; i<tot; i++){
        ans=(ans+f[l][i])%mod;
    }
    printf("%lld\n", ans);

    return 0;
}