HDU1693 Eat the Trees(zerojudge a228)

传送门:

https://zerojudge.tw/ShowProblem?problemid=a228

http://acm.hdu.edu.cn/showproblem.php?pid=1693

【题解】

插头dp第一题(难以置信我高中oi没有写过23333)

方程很简单,自己推一推插头的地方的连通性即可

放几张图跑了

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const int M = 11 + 10, MAX_STATUS = (1 << 12) + 3;
const int mod = 1e9 + 7;

int n, m, a[M][M], tCase = 0;
ll f[M][M][MAX_STATUS];

inline void sol() {
  cin >> n >> m;
  for (int i=1; i<=n; ++i)
    for (int j=1; j<=m; ++j)
      scanf("%d", &a[i][j]);
  int STATUS_SIZE = (1 << m+1) - 1;
  int STATUS_SIZE_T = (1 << m) - 1;
  f[0][m][0] = 1;
  for (int i=1; i<=n; ++i) {
    for (int sta=0; sta<=STATUS_SIZE_T; ++sta) f[i][0][sta << 1] = f[i-1][m][sta];
    for (int j=1; j<=m; ++j)
      for (int sta=0; sta<=STATUS_SIZE; ++sta) {
        bool cur1 = (sta & (1 << j-1)), cur2 = (sta & (1 << j));
        if(a[i][j] == 1) {
          if(cur1 && cur2) f[i][j][sta] = f[i][j-1][sta - (1 << j-1) - (1 << j)];
          else if(cur1 ^ cur2) {
            int STA = (sta | (1 << j-1) | (1 << j));
            f[i][j][sta] = f[i][j-1][STA - (1 << j-1)] + f[i][j-1][STA - (1 << j)];
          } else f[i][j][sta] = f[i][j-1][sta | (1 << j-1) | (1 << j)];
        } else {
          if(!cur1 && !cur2) f[i][j][sta] = f[i][j-1][sta];
          else f[i][j][sta] = 0;
        }
      }
  }
  cout << "Case " << ++tCase << ": There are " << f[n][m][0] << " ways to eat the trees.\n";
}

int main() {
  int T;
  cin >> T;
  while(T--) sol();
    return 0;
}
View Code
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const int M = 11 + 10, MAX_STATUS = (1 << 12) + 3;
const int mod = 1e9 + 7;

int n, m, a[M][M], tCase = 0;
int f[M][M][MAX_STATUS];

inline void sol() {
  cin >> n >> m;
  for (int i=1; i<=n; ++i)
    for (int j=1; j<=m; ++j)
      scanf("%d", &a[i][j]);
  int STATUS_SIZE = (1 << m+1) - 1;
  int STATUS_SIZE_T = (1 << m) - 1;
  f[0][m][0] = 1;
  for (int i=1; i<=n; ++i) {
    for (int sta=0; sta<=STATUS_SIZE_T; ++sta) f[i][0][sta << 1] = f[i-1][m][sta];
    for (int j=1; j<=m; ++j)
      for (int sta=0; sta<=STATUS_SIZE; ++sta) {
        bool cur1 = (sta & (1 << j-1)), cur2 = (sta & (1 << j));
        if(a[i][j] == 1) {
          if(cur1 && cur2) f[i][j][sta] = f[i][j-1][sta - (1 << j-1) - (1 << j)];
          else if(cur1 ^ cur2) {
            int STA = (sta | (1 << j-1) | (1 << j));
            f[i][j][sta] = f[i][j-1][STA - (1 << j-1)] + f[i][j-1][STA - (1 << j)];
            if(f[i][j][sta] >= mod) f[i][j][sta] -= mod;
          } else f[i][j][sta] = f[i][j-1][sta | (1 << j-1) | (1 << j)];
        } else {
          if(!cur1 && !cur2) f[i][j][sta] = f[i][j-1][sta];
          else f[i][j][sta] = 0;
        }
      }
  }
  cout << "Case " << ++tCase << ": " << f[n][m][0] << endl;
}

int main() {
  int T;
  cin >> T;
  while(T--) sol();
    return 0;
}
View Code

上面hdu,下面zerojudge

 

posted @ 2018-08-19 20:54  Galaxies  阅读(565)  评论(0编辑  收藏  举报