码迷,mamicode.com
首页 > 编程语言 > 详细

奇妙的算法—状态压缩动态规划

时间:2015-08-27 23:02:36      阅读:261      评论:0      收藏:0      [点我收藏+]

标签:

华电北风吹
天津大学认知计算与应用重点实验室
日期:2015/8/27

由于代码未调试完全正确论文草稿呈现
poj上一道需要用到状态压缩动态规划,链接http://poj.org/problem?id=3254
网上看到有很多人写出了代码,参考了一个带备忘的自顶向下的动态规划解法,自己写了一个有底向上的动态规划解法
有底向上:

#include<iostream>
#include<math.h>
#include<ostream>
#include<fstream>
using namespace std;

#define max(a,b) ((a)>(b)?(a):(b))
#define MODULO 100000000

int dyna[12][4200];
int map[12][12];
int m, n; /* M stands for row and N stands for line. */

int vali(int b)
{
    int  max = (int)(log(b) / log(2));
    for (int i = 0; i < max; i++)
        if ((b & 1 << i) && (b & 1 << (i + 1)))
            return 0;
    return 1;
}

int main()
{
    ifstream in("C:\\Users\\zhengyi\\Desktop\\Google\\input.txt");
    streambuf *cinbuf = cin.rdbuf(); //save old buf
    cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!
    int i, j, ans = 0;
    cin >> m >> n;
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < 1 << n; j++)
            dyna[i][j] = 0;
    }
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
            cin >> map[i][j];
    }
    int tar = 0;
    for (i = 0; i < n; i++)
        tar += (map[m - 1][i]) << i;
    for (i = 0; i < 1 << n; i++)
    {
        if (~(tar | ~i)==0)
        {
            dyna[m - 1][i] = 1;
        }
    }
    for (i = m - 1; i > 0; i--)
    {
        for (j = 0; j < 1 << n; j++)
        {
            if (dyna[i][j] > 0)
            {
                for (int k = 0; k < 1 << n; k++)
                {
                    if (vali(k))
                        if((j&k)==0)
                            dyna[i - 1][k] += dyna[i][j];
                }
            }
        }
        tar = 0;
        for (j = 0; j < n;j++)
            tar += (map[i - 1][j]) << j;
        for (j = 0; j < 1 << n; j++)
        {
            if (~(tar | ~j) != 0)
                dyna[i - 1][j] = 0;
        }
    }
    int result = 0;
    for (j = 0; j < 1 << n; j++)
    {
        result += dyna[0][j];
    }
    cout << result << endl;
    system("pause");
    return 0;
}

带备忘的自顶向下:

#include<iostream>
#include<math.h>
#include<ostream>
#include<fstream>
using namespace std;

#define max(a,b) ((a)>(b)?(a):(b))
#define MODULO 100000000

/* POJ 3254: Corn Fields */

int dyna[12][4200];
int map[12][12];
int m, n; /* M stands for row and N stands for line. */

int vali(int a, int b)
{
    int i, max = (int)(log(b) / log(2));
    int c = ~(a | (~b));
    if (c)
        return 0;
    else
    {
        for (i = 0; i < max; i++)
            if ((b & 1 << i) && (b & 1 << (i + 1)))
                return 0;
        return 1;
    }
}
int find(int row, int bitway)
{
    int ans = 0, i, tar = 0;
    if (dyna[row][bitway] >= 0) 
        return dyna[row][bitway];
    else
    {
        for (i = 0; i < n; i++)
            tar += map[row][i] * (1 << i);
        tar &= (~bitway);
        if (row == m - 1)
        {
            for (i = 0; i < 1 << n; i++)
            {
                if (vali(tar, i))
                    ans++;
                ans %= MODULO;
            }
            return dyna[row][bitway] = ans % MODULO;
        }
        else
        {
            for (i = 0; i < 1 << n; i++)
            {
                if (vali(tar, i))
                    ans += find(row + 1, i);
                ans %= MODULO;
            }
            return dyna[row][bitway] = ans % MODULO;
        }
    }
}

int main()
{
    ifstream in("C:\\Users\\zhengyi\\Desktop\\Google\\input.txt");
    streambuf *cinbuf = cin.rdbuf(); //save old buf
    cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!
    int i, j, ans = 0;
    cin >> m >> n;
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < 1 << n; j++)
            dyna[i][j] = -1;
    }
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
            cin>>map[i][j];
    }
    ans = max(ans, find(0, 0));
    printf("%d\n", ans);

    system("pause");
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

奇妙的算法—状态压缩动态规划

标签:

原文地址:http://blog.csdn.net/zhangzhengyi03539/article/details/48036691

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!