HDU-1556 方格取数(1) 状态压缩+dp
2012-03-16 15:43
519 查看
这题相对于前面的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 [i]); } cout << ans << endl; } return 0; }
相关文章推荐
- hdu 1565 方格取数(1)(DP 状态压缩)
- hdu 1565 方格取数(1)(DP 状态压缩)
- hdu 1565 方格取数(1) (状态压缩dp)
- HDU 1565 方格取数(1) (状态压缩DP)
- hdu 1565 方格取数(1)(状态压缩dp)
- HDU 1565 - 方格取数(1) 数据有些弱...状态压缩DP
- HDU-1565 方格取数(1) 状态压缩DP
- HDU 1565 方格取数(1)(状态压缩DP)
- HDU1565 方格取数(1) (状态压缩DP)
- HDU 1565 方格取数(1) (状态压缩DP入门题 2)(待更新)
- hdu 1565 方格取数(1) 状态压缩dp
- 状态压缩DP——hdu 1565 方格取数1
- Hdu-1565 方格取数(1) (状态压缩dp入门题
- HDU1565方格取数(1)(状态压缩DP)
- HDU 1565 方格取数(1) (状态压缩 DP)
- hdu 1565 方格取数(1)(状态压缩DP)
- HDU1565 方格取数(1)(状态压缩dp)
- hdu 1565 方格取数(1) 状态压缩dp
- hdu 1565 方格取数(1) (状态压缩DP)
- hdu 1565 方格取数(1)(状态压缩dp)