LightOJ - 1037 Agent 47(状压DP)
2015-10-28 22:50
197 查看
题目大意:有N个敌人,刚开始你有一把枪,每开一枪,可以对敌人造成1点伤害,你杀掉相应的敌人后,可以得到相应敌人的武器。
给你N个敌人的血量,和一个武器伤害矩阵,第i行第j列表示的是第i个敌人的武器,可以对第j个敌人造成1枪val[i][j]的伤害
问至少要开多少枪才能干掉所有的敌人
解题思路:状态压缩,用dp[i]表示干掉i状态下的敌人需要开多少枪
给你N个敌人的血量,和一个武器伤害矩阵,第i行第j列表示的是第i个敌人的武器,可以对第j个敌人造成1枪val[i][j]的伤害
问至少要开多少枪才能干掉所有的敌人
解题思路:状态压缩,用dp[i]表示干掉i状态下的敌人需要开多少枪
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int N = 20; const int S = (1 << 15) + 10; int n, cas = 1; int life , mat ; int dp[S]; char str ; void init() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &life[i]); for (int i = 0; i < n; i++) { scanf("%s", str); for (int j = 0; j < n; j++) { mat[i][j] = str[j] - '0'; } } } void solve() { memset(dp, 0x3f, sizeof(dp)); dp[0] = 0; queue<int> Q; Q.push(0); while (!Q.empty()) { int s = Q.front(); Q.pop(); if (s == (1 << n) - 1) continue; for (int i = 0; i < n; i++) { if (s & (1 << i)) continue; bool flag = false; if (dp[s] + life[i] < dp[s | (1 << i)]) { dp[s | (1 << i)] = dp[s] + life[i]; flag = true; } for (int j = 0; j < n; j++) { if ((s & (1 << j) ) && mat[j][i]) { int t = life[i] / mat[j][i]; t += (life[i] % mat[j][i] ? 1 : 0); if (dp[s | (1 << i)] > dp[s] + t) { dp[s | (1 << i)] = dp[s] + t; flag = true; } } } if (flag) Q.push(s | (1 << i)); } } printf("Case %d: %d\n", cas++, dp[(1 << n) - 1]); } int main() { int test; scanf("%d", &test); while (test--) { init(); solve(); } return 0; }
相关文章推荐
- EffectiveC#02--仅在对基类进行强制更新时才使用new修饰符
- 【NOIP】10.28集训总结
- [LintCode] Subsets
- [BZOJ3751][NOIP2014] 解方程
- Meteor 简介
- Linux 装B之作酷炫小工具
- ios9有哪些新特性?
- uft飞机订票系统参数化
- 如何注册免费的dns
- 8421BCD编码-20151027
- AFNetworking
- Redis简介及3.0.2编译安装
- 学习Andorid开发第一天
- Android开发之如何保证Service不被杀掉(broadcast+system/app)
- Android Handler 消息机制详解
- SVN更新失败,提示locked 怎么破
- 大神们的微博
- MD5加盐进行加密 以及更完全的加密方法HMAC+MD5的方式进行加密
- const||C++
- Ruby测试小代码[计算50以内的素数]