Topcoder srm 653 div.2 1000 - SingingEasy(区间DP)
2015-03-26 11:19
225 查看
题意:
给出一个序列,请你找出两个没有交且并为全集的子序列,使得每个子序列相邻两位之间的数字差的绝对值之和最小。
思路:
DP....(dp弱渣, 折腾了好久请教了人才会>,<..
dp[i][j] 表示一人最后一个取的位置是i, 一人最后一个取的位置是j.
分两种情况:
1.i-j>1: dp[i][j] = dp[i-1][j] + abs(pitch[i-2]-pitch[i-1]) 让A一直取数..
2.i-j=1: 1) A只取i, 其他的都给B.
2)A取j, 枚举A上一次取的位置k,B取i, 上一次取k: res = min(res, dp[j][k] + abs(pitch[i-1]-pitch[k-1]))
理解: 两个人会把其中一个位置当做他取的最后一个位置, 那另一个人取的最后一个位置就是最后一个数了. 可以先想比如只有3个人, 这样写是可以把所有的情况涵盖的,相当于问题的子问题.
AC.
给出一个序列,请你找出两个没有交且并为全集的子序列,使得每个子序列相邻两位之间的数字差的绝对值之和最小。
思路:
DP....(dp弱渣, 折腾了好久请教了人才会>,<..
dp[i][j] 表示一人最后一个取的位置是i, 一人最后一个取的位置是j.
分两种情况:
1.i-j>1: dp[i][j] = dp[i-1][j] + abs(pitch[i-2]-pitch[i-1]) 让A一直取数..
2.i-j=1: 1) A只取i, 其他的都给B.
2)A取j, 枚举A上一次取的位置k,B取i, 上一次取k: res = min(res, dp[j][k] + abs(pitch[i-1]-pitch[k-1]))
理解: 两个人会把其中一个位置当做他取的最后一个位置, 那另一个人取的最后一个位置就是最后一个数了. 可以先想比如只有3个人, 这样写是可以把所有的情况涵盖的,相当于问题的子问题.
AC.
#line 7 "SingingEasy.cpp" #include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <stack> #include <fstream> #include <numeric> #include <iomanip> #include <bitset> #include <list> #include <stdexcept> #include <functional> #include <utility> #include <ctime> using namespace std; #define PB push_back #define MP make_pair #define REP(i,n) for(i=0;i<(n);++i) #define FOR(i,l,h) for(i=(l);i<=(h);++i) #define FORD(i,h,l) for(i=(h);i>=(l);--i) typedef vector<int> VI; typedef vector<string> VS; typedef vector<double> VD; typedef long long LL; typedef pair<int,int> PII; int dp[2005][2005]; class SingingEasy { public: int solve(vector <int> pitch) { int len = pitch.size(); if(len <= 2) return 0; dp[1][0] = 0; for(int j = 2; j <= len; ++j) { dp[j][0] = dp[j-1][0] + abs(pitch[j-2]-pitch[j-1]); } dp[2][1] = 0; for(int i = 3; i <= len; ++i) { for(int j = 1; j < i; ++j) { if(i - j > 1) { dp[i][j] = dp[i-1][j] + abs(pitch[i-2]-pitch[i-1]); } else { int res = 1e9+5; for(int k = 1; k < j; ++k) { res = min(res, dp[j][k] + abs(pitch[i-1]-pitch[k-1])); } dp[i][j] = min(res, dp[j][0]); } } } int ans = dp[len][0]; for(int i = 1; i < len; ++i) { ans = min(ans, dp[len][i]); } return ans; }
相关文章推荐
- Topcoder srm 653 div.2 500 - RockPaperScissorsMagicEasy(DP)
- TopCoder SRM 672 Div2 Problem 1000 - Tdetectived2 (状压dp)
- srm 653 div2 1000(dp)
- TopCoder SRM 663 Div2 Problem 1000 - CheeseRolling (状压dp)
- topcoder SRM 654 DIV2 1000 SuccessiveSubtraction2 题解(dp)
- TopCoder SRM 642 Div.2 1000 --二分+BFS
- TopCoder SRM 653 Div2 Problem 500 - RockPaperScissorsMagicEasy (DP)
- TopCoder SRM 648 Div2 Problem 1000 - ABC (DP)
- srm 301 div2 1000 (经典dp, 括号匹配)
- Topcoder SRM 585 DIV2 解题报告 //缺1000
- Topcoder SRM 662 Div1, ExactTree,DP
- Topcoder SRM 565 Div.2
- [补集转换 DP] Topcoder SRM 509 DIV1 Hard. NumberLabyrinthDiv1
- srm 308 div2 1000(DP, 离散背包+连续背包)
- TopCoder SRM 657 Div2 Problem 1000 - PolynomialRemainder(数学)
- Topcoder SRM 144 Div1 550(数学和dp问题求方案数,很有意思)
- Topcoder SRM 636 div2 1000
- TopCoder SRM 666 Div2 Problem 999 - WalkOverATreeDiv2 (树形DP)
- Topcoder SRM 148 Div2 1000(dfs搜索+hash判重)
- Topcoder SRM 517 DIV2 1000 CuttingGrass