Topcoder SRM 497 DIV2 1000 MakeSquare
2015-03-23 23:03
351 查看
题意:给你一个字符串,对这个字符串有三种操作。
1)任意位置插入任意一个字符
2)任意位置删除一个字符
3)改变任意位置的一个字符。
问你最后要经过最少的步数使得这个字符串由两个相同的字符串串联构成。
解题思路:枚举将两个字符串分成两个串,然后对这两个串求改变k(0-len)次的最长公共子序列即可。
解题代码:
View Code
1)任意位置插入任意一个字符
2)任意位置删除一个字符
3)改变任意位置的一个字符。
问你最后要经过最少的步数使得这个字符串由两个相同的字符串串联构成。
解题思路:枚举将两个字符串分成两个串,然后对这两个串求改变k(0-len)次的最长公共子序列即可。
解题代码:
// BEGIN CUT HERE /* */ // END CUT HERE #line 7 "MakeSquare.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; char str[1000]; int len ; int dp[200][200][70]; int solve(int x) { memset(dp,0,sizeof(dp)); int same = 0 ; for(int i = 1;i <= x ;i ++) for(int j = x+1 ;j <= len ;j ++) { same = 0 ; if(str[i] == str[j]) { same = 1; } if(same == 0 ) for(int k = 0 ; k <= len ; k ++) { dp[i][j][k+1] = max(dp[i][j][k+1],dp[i-1][j-1][k] + 1); } for(int k = 0 ; k <= len; k ++) { dp[i][j][k] = max(dp[i][j][k],dp[i-1][j-1][k] + same); dp[i][j][k] = max(dp[i][j][k],dp[i][j-1][k] ); dp[i][j][k] = max(dp[i][j][k],dp[i-1][j][k] ); } } int len1 = x; int len2 = len - x; //printf("%d %d %d\n",len1,len2,dp[x][len]); int ans = len; for(int k = 0; k <= len; k ++) { ans = min(ans,len1 - dp[x][len][k] + len2 - dp[x][len][k] + k); } return ans; } class MakeSquare { public: int minChanges(string S) { len = S.size(); int ans = len; for(int i = 0 ;i < len; i ++) str[i+1] = S[i]; for(int i = 1;i < len;i ++) ans = min(ans,solve(i)); return ans; } // BEGIN CUT HERE public: 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() { string Arg0 = "abcdabgcd"; int Arg1 = 1; verify_case(0, Arg1, minChanges(Arg0)); } void test_case_1() { string Arg0 = "abcdeabce"; int Arg1 = 1; verify_case(1, Arg1, minChanges(Arg0)); } void test_case_2() { string Arg0 = "abcdeabxde"; int Arg1 = 1; verify_case(2, Arg1, minChanges(Arg0)); } void test_case_3() { string Arg0 = "aabcaabc"; int Arg1 = 0; verify_case(3, Arg1, minChanges(Arg0)); } void test_case_4() { string Arg0 = "aaaaabaaaaabaaaaa"; int Arg1 = 2; verify_case(4, Arg1, minChanges(Arg0)); } // END CUT HERE }; // BEGIN CUT HERE int main() { MakeSquare ___test; ___test.run_test(-1); return 0; } // END CUT HERE
View Code
相关文章推荐
- Topcoder SRM 635 Div2 1000 (一种 O(n) 求一棵树中最长连续边 长度的方法)
- TopCoder SRM 652 Div2 Problem 1000 - NoRightTurnDiv2 (几何 + 贪心)
- topcoder SRM 654 DIV2 1000 SuccessiveSubtraction2 题解(dp)
- Topcoder SRM 148 Div2 1000(dfs搜索+hash判重)
- TopCoder SRM 634 Div2 Problem 1000 - SpecialStrings
- Topcoder SRM 146 Div2 1000(dfs搜索,经典过桥问题,很有意思)
- TopCoder SRM 660 Div2 Problem 1000 - Powerit (数论)
- TOPCODER SRM 686 div2 1000
- TopCoder SRM 672 Div2 Problem 1000 - Tdetectived2 (状压dp)
- Topcoder SRM 635 div2 1000
- Topcoder SRM 640 Div2 1000(巧妙数学题)
- Topcoder SRM 636 Div2 1000(切蛋糕,最后一块给自己。最小值中求最大值,二分+枚举)
- Topcoder SRM 585 DIV2 解题报告 //缺1000
- TopCoder SRM 648 Div2 Problem 1000 - ABC (DP)
- Topcoder SRM 585 DIV2 解题报告 //缺1000
- Topcoder SRM 616 Div2 1000 TwoLLogo
- TopCoder SRM 663 Div2 Problem 1000 - CheeseRolling (状压dp)
- Topcoder SRM 636 div2 1000
- Topcoder SRM 517 DIV2 1000 CuttingGrass
- Topcoder SRM 543 DIV2 1000 EllysThreeRivers & DIV1 500 EllysRivers