zoukankan      html  css  js  c++  java
  • HDU1556 方格取数(1) 状态压缩+dp

    这题相对于前面的little kings 来说简单了一些,没有了步数的限制,dp方程也简洁了不少。
    只需要考虑当前状态是否与上一个状态冲突即可。

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #define MAXN 20000
    using namespace std;

    long long f[25][MAXN];
    int N, M, map[25][25], s[MAXN];

    inline long long max(long long &x, long long &y)
    {
    return x < y ? y : x;
    }

    void dfs(int l, int state)
    { // 枚举出每一行的所有状态
    if (l == N)
    {
    s[++M] = state;
    return;
    }
    dfs(l+1, state<<1);
    if (!(state&1))
    dfs(l+1, state<<1|1);
    }

    inline bool judge(int s1, int s2)
    {
    if (s[s1] & s[s2])
    return false;
    else
    return true;
    }

    inline int get(int x, int k)
    {
    int ans = 0;
    for (int i = N, a = s[k]; a; --i, a >>= 1)
    {
    if (a & 1)
    ans += map[x][i];
    }
    return ans;
    }

    void dp()
    {
    for( int i = 1; i <= M; ++i )
    f[1][i] = get(1,i);
    for (int i = 2; i <= N; ++i)
    {
    for (int j = 1; j <= M; ++j)
    {
    int res = get(i, j);
    for (int k = 1; k <= M; ++k)
    {
    if (judge(j, k))
    {
    f[i][j] = max(f[i][j], f[i-1][k]+res);
    }
    }
    }
    }
    }

    int main()
    {
    long long ans;
    while (scanf("%d", &N) == 1)
    {
    M = 0;
    ans = 0;
    dfs(0, 0);
    for (int i = 0; i <= N; ++i)
    {
    for (int j = 0; j <= M; ++j)
    f[i][j] = 0;
    }
    for (int i = 1; i <= N; ++i)
    {
    for (int j = 1; j <= N; ++j)
    {
    scanf("%d", &map[i][j]);
    }
    }
    dp();
    for (int i = 1; i <= M; ++i)
    {
    ans = max(ans, f[N][i]);
    }
    cout << ans << endl;
    }
    return 0;
    }


     

  • 相关阅读:
    pydbg系列[1]
    内核参与方式
    Debugging with GDB阅读[6]
    宏技巧解读
    右键-发送到-邮件接收者没有了的解决方法
    获得文件版本信息
    解决动态生成的SQL中特殊字符的问题 QuotedStr function
    CreateFileMapping的MSDN翻译和使用心得
    关闭Windows自动播放功能
    清凉明目茶
  • 原文地址:https://www.cnblogs.com/Lyush/p/2400410.html
Copyright © 2011-2022 走看看