hiho 1271 舰队游戏 状压dp 贪心 模拟
来源:互联网 发布:影视飞飞cms 编辑:程序博客网 时间:2024/06/06 02:04
题目
题目链接:http://hihocoder.com/problemset/problem/1271
题目来源:hiho的比赛。
简要题意:给定对空和对舰的飞机还有一个航母,给定计算公式,要你弄个奇怪的方案。
题解
题意非常扭曲,但是的确算是个好题吧。
对于
30% 的数据,可以进行搜索,枚举每个位置放哪个飞机。对于大数据可以采用状压dp的方式。
最多
16 个位置,状态空间为216 。由于题目中的限制,你无法直接去算整个结果。
可以分别计算两边的最大值然后再进行一个最后的判断。
dp[i][j] 表示前i 个对?飞机,位置使用状况为j 的最大对?伤害。搞完之后根据题目之中的条件进行一个判断就可以了。
需要注意的是如果直接这么做还是无法通过所有数据的。
可以发现任何位置对同种的伤害越大越好。
于是可以排序,只留下最大的
n×m 个对空,对舰的然后去做。开始直接搞,没贪心各种WA,TLE一晚上,第二天醒来就想明白了。
题目本身还是非常不错的,代码量还是有点长。
代码
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define fi first#define se secondusing namespace std;typedef long long LL;typedef pair<int,int> PII;typedef pair<LL,LL> PLL;// headconst int N = 10;const int T = 1005;const int M = 1 << 16;const int INF = -1;int a[N][N];vector<int> b, c;vector<PII> d;int dp[2][M];int res[2][M];bool exist = false;bool yes = false;int ans = 0;int n, m, t, s, tt, x, nm, mx;bool ck(int st) { int temp[5]; memset(temp, 0, sizeof temp); for (int i = 0; i < (n*m); i++) { if ((1 << i) & st) { temp[d[i].fi] = true; } } for (int i = 0; i < n; i++) { if (!temp[i]) return false; } return true;}void getRes(int *tar, const vector<int> &v) { memset(dp, INF, sizeof dp); dp[0][0] = 0; int cur = 1, pre = 0; for (int i = 0; i < v.size(); i++) { for (int j = 0; j < mx; j++) { if (dp[pre][j] == INF) continue; dp[cur][j] = max(dp[cur][j], dp[pre][j]); for (int k = 0; k < nm; k++) { if ((1 << k) & j) continue; int nxt = j | (1<<k); dp[cur][nxt] = max(dp[cur][nxt], dp[pre][j] + a[d[k].fi][d[k].se] * v[i]); } } swap(cur, pre); } memcpy(tar, dp[pre], sizeof dp[pre]);}void solve() { getRes(res[0], b); getRes(res[1], c); for (int i = 0; i < mx; i++) { if (res[0][i] < s) continue; exist = true; int cur = (mx-1) ^ i; if (res[1][cur] < ans) continue; if (res[1][cur] > ans) { ans = res[1][cur]; yes = false; } if (ck(cur)) { yes = true; } }}void input(vector<int> &b) { for (int i = 0; i < t; i++) { scanf("%d", &x); if (x) b.push_back(x); } sort(b.begin(), b.end()); reverse(b.begin(), b.end()); while (b.size() > d.size()) { b.pop_back(); }}int main() { scanf("%d", &tt); while (tt--) { scanf("%d%d%d%d", &n, &m, &t, &s); nm = n * m; mx = 1 << nm; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { scanf("%d", a[i]+j); d.push_back(make_pair(i, j)); } } input(b); input(c); exist = yes = false; ans = 0; solve(); if (!exist) { puts("Not Exist"); } else { printf("%d\n%s\n", ans, (yes ? "Yes" : "No")); } d.clear(); b.clear(); c.clear(); } return 0;}
0 0
- hiho 1271 舰队游戏 状压dp 贪心 模拟
- HihoCoder 1271舰队游戏(二进制枚举、贪心)
- [Offer收割]编程练习赛1 hihocoder 1271 舰队游戏 (状态压缩+贪心 好题)
- hiho 1165 益智游戏(因子个数+贪心)
- 【贪心】【noip模拟】皇后游戏
- 国王游戏(贪心+模拟)
- Loi 模拟赛 贪心+模拟+DP+数论
- hiho 1270 建造基地 dp 完全背包 模拟
- hiho #1051 : 补提交卡 (hiho模拟面试题2 - google在线技术笔试模拟 贪心+枚举)
- NOIP模拟题[贪心][DP][数论]
- 做(do) (贪心模拟 dp)
- #bzoj2240#积木游戏(DP? 贪心?)
- hiho模拟面试题2 补提交卡 (贪心,枚举)
- 【hiho挑战赛24 A&B&C】贪心和期望dp惨烈的后缀自动机
- hiho一下 第109周 Tower Defense Game 树DP+贪心
- hiho 1615 矩阵游戏II [Offer收割]编程练习赛33 Problem A 贪心暴力
- Hiho 1385 模拟,细节
- 10.10 高校模拟赛 贪心模拟+BFS+DP
- php 学习笔记 -- 日期(四)
- 一个不错的android学习网站
- 白话Spring(基础篇)---声明式事务(2)
- mysql-5.7.11-winx64.zip解压缩安装时root的默认密码
- android contentprovider limit限定
- hiho 1271 舰队游戏 状压dp 贪心 模拟
- C++中的RTTI机制详解
- UIKeyboardType
- Android Studio配置SVN服务器
- ffmpeg推流器
- sql批量替换字段里的字符串
- Vector的用法
- C语言.h和.c的理解与探讨
- VS2013编译eXosip2-4.1.0