【ZOJ3471】Most Powerful, 思路+源代码+解题报告(好久没写解题报告了……)【目标达成:0.1%】
2012-08-01 23:46
302 查看
/** Problem:ZOJ3471-Most Powerful. Reference:http://blog.csdn.net/magicnumber/article/details/6182891 Knowledge point:状态压缩DP Thought: 根据炮兵阵地(那是别的题)和这道题,还有一次多校的经验(就是那个类似拼图的那个题,给你 几个块问你能拼多大的长方形),貌似状态数少的,就可以用状态压缩。 比如这道题,N <= 10,并且一个气体只有“用”和“没用”两种属性,那么就可以用二进制表示状态。 2^10可以用一个int存储。那么rp[i]中对应的i的二进制表示,就代表了一种状态。状态的转移就在 rp[i]和rp[j]之间进行。 (rp数组和dp数组表示的意思相同,后文不再赘述。由于本人靠人品进行动态规划,故起名如此) 状态转移方程为: dp[i|cst[j]]=Max(dp[i|cst[j]],dp[i]+map[k][j]); map[k][j]表示的是用j撞k获得的能量值。 唔,跟我第一次想的不一样。就是说,存在类似 0100000,0010000,00010000...(分别表示总共8个气体,用了第二个,第三个,第四个气体,用以举例子) 这种状态,我刚开始想的是直接就是01100000(就是直接两个气体对撞)…… 【注意,我的想法是错误的,这是写给我自己看的,你们无视就好】 那么0100000代表的就是第二个气体已经用过了。 注意,跟谁撞了,这不重要。重要的是用掉了哪个气体。 ————————————关于dp[i|csj[j]]=max(dp[i|cst[j]],dp[i]+map[k][j]);的证明如下—————————————— 假设剩下最后两种气体 那么最优解一定是两种气体i,j中map[i][j],map[j][i]最大的。 而且,对于最优解来说,这时候(剩下两种气体的时候)已经获得的能量肯定是n-2种气体对撞获得能量最大的 符合最优子结构。 状态转移方程也是根据以上推出来的。 这个。。。只能意会啊,我真的证明不明白T^T,自己用样例看一下就知道了。 */ #include <iostream> #include <cstring> #include <cstdlib> #include <algorithm> #include <cstdio> using namespace std; const int MAX_SIZE = 15; const int MAX_BINARY = 1024 + 1; // avoid overflow. int power[MAX_SIZE][MAX_SIZE]; int dp[MAX_BINARY]; int bin[] = { 1,2,4,8,16,32,64,128,256,512,1024 } ;// 2^10 = 1024; int solve(int N) { int maxV = 0; for(int i = 0 ; i < bin ; i++) //expand every state. { for(int j = 0 ; j < N; j++) { if( ( i & bin[j] ) != 0 ) continue; //gas j has been used. for(int k = 0 ; k < N ; k++) { if( ((i & bin[k])==0) && (k != j) ) { dp[i | bin[j]] = max(dp[i | bin[j]],dp[i]+power[k][j]); } } } } for(int i = 0 ; i < bin ; i++) { maxV = max(maxV,dp[i]); } return maxV; } int main() { #ifndef ONLINE_JUDGE freopen("B:\\acm\\SummerVacation\\DP-II\\A.in","r",stdin); freopen("B:\\acm\\SummerVacation\\DP-II\\A.out","w",stdout); #endif int N,res; while(scanf("%d",&N) != EOF && N) { memset(dp,0,sizeof(dp)); for(int i = 0 ; i < N ; i++) { for(int j = 0 ; j < N ; j++) { scanf("%d",&power[i][j]); } } res = solve(N); printf("%d\n",res); } #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
相关文章推荐
- 【HDU4313】Matrix 多校 解题报告+AC代码+思路+算法正确性证明,此为Kruskal贪心简单版本,恶心版本稍后放出【目标达成 0.2%】
- 【HDU4313】Matrix 多校 解题报告+AC代码+思路+算法正确性证明,此为Kruskal贪心恶心版本,非自虐倾向慎入!建议想找解题报告的童鞋看简单版本的,这个我写给自己【目标达成 0.2%】
- 【HDU3415】Max Sum of Max-K-sub-sequence,思路+解题报告+AC代码+自虐般疯狂吐槽【0.3%达成!】
- 【HDU1686】Oulipo 思路+解题报告+代码+KMP算法个人理解 【0.5%达成】
- 【HDU4313】 - Matrix - 树状DP Version 思路+解题报告+AC代码【0.4%达成】
- Leetcode / C++ / 502. IPO 解题报告+源代码
- 【0.9%】SPOJ7758 Grwoing Strings 解题报告 + AC代码 + 思路 + AC自动机简短总结
- 【UVa10167】 Birthday Cake,思路+代码+解题报告
- 华为2018软件岗笔试题解题思路和源代码分享
- 9-25考试第三题解题报告(还是写了指针翻译神马的都是浮云感觉好久不说话连话都不会说了233333333QVO)
- LeetCode - 136. Single Number - ( C++ ) - 解题报告 - 位运算思路 xor
- 北大ACM 解题思路和源代码
- 【HDU1272】小希的迷宫解题报告,数据+思路+代码
- 【HDU2780 - Su-Su-Sudoku】 解题报告+思路+代码,差点一次AC T^T
- 【POJ2255】Tree Recovery解题报告 思路 + 数据 +代码
- foj 1844 题解题报告 + 源代码
- 【POJ1198 Solitaire 】 思路+解题报告+测试数据生成器
- HDU 1066 解题报告 详细思路+code
- 【POJ2488】 A knight's Journey 解题报告 测试数据+代码+思路
- 【POJ1011 Sticks】解题报告+思路+代码