SRM588 KeyDungeonDiv1
来源:互联网 发布:程序员赚钱的方法 编辑:程序博客网 时间:2024/05/04 01:03
任意门:http://community.topcoder.com/stat?c=problem_statement&pm=12714
很典型的状压DP。
如果已经通过的是门A和门B的话,不论先过A还是先过B,用掉的钥匙数和得到的钥匙数是一样的。但是请注意:使用的白钥匙可能不一样。
换而言之,用于开红色门的白钥匙数可能不一样(同理,用于开绿门的白钥匙数也不一样,只需统计一个就可以了)
所以压缩的状态为已经通过的门,和剩余的红钥匙数(和在红门上使用的白钥匙数是互补的),去DFS吧= =
// BEGIN CUT HERE// END CUT HERE#line 5 "KeyDungeonDiv1.cpp"#include <cstdio> #include <cstring> #include <cctype>#include <cstdlib> #include <ctime> #include <climits> #include <cmath> #include <iostream> #include <string> #include <vector> #include <set> #include <map> #include <list> #include <queue> #include <stack> #include <deque> #include <algorithm> using namespace std;typedef long long ll;#define SZ(x) ((int)(x.size()))const int INF = 0x3f3f3f3f;int n, tot, ans;struct Door{int d1,d2;int k1,k2,k3;}door[12];int dp[1<<12][131];void dfs(int state,int key1,int key2,int key3){if (dp[state][key1]>0) return;dp[state][key1] = key1+key2+key3;if (ans<dp[state][key1]) ans=dp[state][key1];if (state==(1<<n)-1) return;for (int i=0;i<n;i++){if (state&(1<<i)) continue;int d1=door[i].d1, d2=door[i].d2, k1=door[i].k1, k2=door[i].k2, k3=door[i].k3;if (key1>=d1 && key2>=d2)dfs(state|(1<<i), key1-d1+k1, key2-d2+k2, key3+k3);else{int les = max(0,d1-key1)+max(0,d2-key2);if (key3>=les) dfs(state|(1<<i), max(0,key1-d1)+k1, max(0,key2-d2)+k2, key3-les+k3);}}}class KeyDungeonDiv1{public:int maxKeys(vector <int> doorR, vector <int> doorG, vector <int> roomR, vector <int> roomG, vector <int> roomW, vector <int> keys){int ret;n = SZ(doorR); tot = 1<<n;for (int i=0;i<n;i++){door[i].d1=doorR[i];door[i].d2=doorG[i];door[i].k1=roomR[i];door[i].k2=roomG[i];door[i].k3=roomW[i];}for (int i=0;i<tot;i++)for (int k=0;k<=130;k++)dp[i][k]=0;ans = 0;dfs(0,keys[0],keys[1],keys[2]);return ret = ans;}// BEGIN CUT HEREpublic:void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); }private:template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }void test_case_0() { int Arr0[] = {1, 2, 3}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 4, 9}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0, 0, 10}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {0, 8, 9}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {1, 0, 8}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arr5[] = {3, 1, 2}; vector <int> Arg5(Arr5, Arr5 + (sizeof(Arr5) / sizeof(Arr5[0]))); int Arg6 = 8; verify_case(0, Arg6, maxKeys(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5)); }void test_case_1() { int Arr0[] = {1, 1, 1, 2}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 2, 3, 1}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {2, 1, 0, 4}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1, 3, 3, 1}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {1, 0, 2, 1}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arr5[] = {0, 4, 0}; vector <int> Arg5(Arr5, Arr5 + (sizeof(Arr5) / sizeof(Arr5[0]))); int Arg6 = 4; verify_case(1, Arg6, maxKeys(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5)); }void test_case_2() { int Arr0[] = {2, 0, 4}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {3, 0, 4}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0, 0, 9}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {0, 0, 9}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {8, 5, 9}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arr5[] = {0, 0, 0}; vector <int> Arg5(Arr5, Arr5 + (sizeof(Arr5) / sizeof(Arr5[0]))); int Arg6 = 27; verify_case(2, Arg6, maxKeys(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5)); }void test_case_3() { int Arr0[] = {5, 3, 0, 0}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 1, 2, 1}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0, 9, 2, 4}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {2, 9, 2, 0}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {0, 9, 1, 1}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arr5[] = {1, 1, 0}; vector <int> Arg5(Arr5, Arr5 + (sizeof(Arr5) / sizeof(Arr5[0]))); int Arg6 = 32; verify_case(3, Arg6, maxKeys(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5)); }void test_case_4() { int Arr0[] = {9,5,10,8,4,3,0,8,4,1,3,9}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {9,10,0,8,9,4,3,8,1,8,10,4}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {1,2,0,2,3,3,5,3,1,3,0,5}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {5,2,5,0,5,2,3,4,0,0,5,2}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {1,5,1,2,0,4,4,0,3,3,1,3}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arr5[] = {5,0,1}; vector <int> Arg5(Arr5, Arr5 + (sizeof(Arr5) / sizeof(Arr5[0]))); int Arg6 = 16; verify_case(4, Arg6, maxKeys(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5)); }// END CUT HERE};// BEGIN CUT HEREint main(){KeyDungeonDiv1 ___test;___test.run_test(-1);return 0;}// END CUT HERE
- SRM588 KeyDungeonDiv1
- SRM588 Div1Medium KeyDungeonDiv1
- SRM588 Div1Medium KeyDungeonDiv1
- SRM588 div2
- srm588 div1
- topcoder SRM588 DV2 1000
- topcoder SRM588 DIV1 解题报告
- JSP文件是否有必要放在WEB-INF下
- Android用户界面中回调函数
- 求解常微分方程边值问题之试射法
- c++qsort函数用法 简练讲解
- 查看Linux磁盘空间大小
- SRM588 KeyDungeonDiv1
- C语言中数组初始化为{X},{X,},{}以及无初始化的比较
- 一些Android开发小提示
- 处方导入
- 网站收藏
- Eclipse运行SWT出错(Cannot load 32-bit SWT libraries on 64-bit JVM)
- 工序导入
- Tomcat配置数据源--方案三
- Android系统的一些需要改进的地方