zoukankan      html  css  js  c++  java
  • HDU 1565 方格取数(1)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1565

    思路:跟上一篇 POJ 的状压dp很类似在这里就不过多阐述了

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define M 20000
     5 using namespace std;
     6 typedef long long LL;
     7 LL n, pass[M], now[22][M], mp[25][25];
     8 LL dp[22][M];//这里之所以不开1<<n 是因为虽然1<<n很大,但是其中有效状态比较小所以只开M个就足够了
     9 bool check(int x, int y) {
    10     return (pass[x] & pass[y]);
    11 }
    12 int main()
    13 {
    14     ios::sync_with_stdio(false);
    15     while (cin >> n) {
    16         if (n == 0) {
    17             cout << "0" << endl;
    18             continue;
    19         }
    20         memset(pass, 0, sizeof(pass));
    21         memset(now, 0, sizeof(now));
    22         memset(dp, 0, sizeof(dp));
    23         for (int i = 1; i <= n; i++)
    24             for (int j = 1; j <= n; j++)
    25                 cin >> mp[i][j];
    26         int cnt = 0;
    27         for (int i = 0; i < (1 << n); i++)
    28             if (!(i&(i << 1)))//将可行状态保存下来
    29                 pass[cnt++] = i;
    30         for (int i = 1; i <= n; i++) {
    31             for (int j = 0; j < cnt; j++) {
    32                 int t = n;
    33                 for (int k = 1; k < (1 << n); k<<=1) {
    34                     if ((pass[j]&k))
    35                         now[i][j] += mp[i][t];//now[i][j]代表第i行第j种状态的获取值
    36                     t--;
    37                 }
    38             }
    39         }
    40         for (int i = 0; i < cnt; i++)
    41             dp[1][i] = now[1][i];
    42         for (int i = 2; i <= n; i++) {
    43             for (int j = 0; j < cnt; j++) {
    44                 for (int k = 0; k < cnt; k++) {
    45                     if (!check(j, k))
    46                         dp[i][j] = max(dp[i][j], dp[i - 1][k] + now[i][j]);
    47                 }
    48             }
    49         }
    50         LL ans = 0;
    51         for (int i = 0; i < cnt; i++)
    52             ans = max(dp[n][i], ans);
    53         cout << ans << endl;
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    后向边
    图的割点、桥和双连通分支的基本概念
    Hihocoder 1062 最近公共祖先1
    会场问题 差分解法
    POJ2976 01分数规划 普通题
    Hihocoder 1049
    hihocoder 1050树中最长路
    Hihocoder 1055
    POJ1463
    C语言|博课作业02
  • 原文地址:https://www.cnblogs.com/wangrunhu/p/9480085.html
Copyright © 2011-2022 走看看