POJ3781-3786(Unknown Summer Training ID 8911 0x03 on hust oj)(枚举、贪心、动态规划)
一共9道题,完成前6道。
A:
问题:输入10个数,输出10个数中第3大的数。
STL sort函数水过。
B:
问题:输入n个数字,将这些数字分成若干组,使每组数字的和相同,只有连续的数字才能被分在同一组。给出一种分法使每组数字的和最小,输出该最小值。
思路:枚举 + 贪心。至多循环n次。第i次循环: 将第i个数加入第一组,之后判断后续的数是否能按第一组的和分组。若能,则输出该和的值,并终止循环;若不能,立即跳入下一个循环。
C:
问题:有n层楼,测试玻璃球在几楼落下刚好破碎。现有m个玻璃球,给出一个测试方案使测试必然成功,且测试的次数最少,输出该最少值。
思路:动态规划。dp[n][m] = max(f[k]); f[k] = max(dp[k - 1][m - 1], dp[n -k][m]);(其中f[k]为n层楼,m个球时,先测试第k层楼)。
D:
问题:n个数字按顺序输入,每当输入第奇数个数字时,输出已输入数字的中位数。
水过。
E:
问题:输入一个只含数字的字符串,输出该字符串的下一个排列方式。
水题,STL next_permutation水过。
F:
问题:输入字符串的长度n,及字符串中'1'字符的相邻数m,输出符合条件的只含'0'、'1'的字符串的种数。
思路:动态规划。只需考虑0在输入字符串中第一次出现的位置。f[n][m] = f[n - 1][m] + f[n - 2][m] + f[n - 3][m - 1] + f[n - 4][m - 2] + ... + f[n - x][0].
最后附BCF代码:
B:
#include<iostream> using namespace std; int num[10000]; int main(){ int N; cin >> N; while(N--){ int index, M; int result = 0; bool found = false; cin >> index >> M; for(int i = 0; i < M; i++) cin >> num[i]; for(int i = 0; i < M; i++){ result += num[i]; int temp = 0; for(int j = i + 1; j < M; j++){ temp += num[j]; if(temp < result) continue; else if(temp == result){ temp = 0; }else{ break; } } if(temp == 0){ cout << index << " " << result << endl; break; }else{ continue; } } } }
C:
#include<iostream> using namespace std; int f[1100][60]; int main(){ for(int i = 1; i < 1100; i++) f[i][1] = i; for(int i = 1; i < 60; i++) f[1][i] = 1; for(int i = 1; i < 1100; i++) for(int j = 2; j < 60; j++){ int min = 10000000; for(int k = 1; k <= i; k++){ int temp = 1 + max(f[k-1][j-1], f[i - k][j]); if(min > temp) min = temp; } f[i][j] = min; } int N; cin >> N; while(N--){ int index, x, y; cin >> index >> x >> y; cout << index << " " << f[y][x] << endl; } // for(int i = 1; i < 100; i++){ // for(int j = 1; j< 10; j++) // cout << f[i][j] <<" "; // cout << endl; // } }
F:
#include<iostream> using namespace std; int dp[200][200]; int main(){ dp[0][0] = 1; dp[1][0] = 2; for(int i = 2; i < 110; i++){ dp[i][0] = dp[i - 1][0] + dp[i - 2][0]; dp[i][i-1] = 1; } for(int i = 1; i < 110; i++){ for(int j = 1; j < i; j++){ dp[i][j] += dp[i - 1][j]; for(int k = 0; k <= j; k++) dp[i][j] += dp[i - 2 - k][j - k]; } } int N; cin >> N; while(N--){ int index, x, y; cin >> index >> x >> y; cout << index << " " << dp[x][y] << endl; } // for(int i = 0; i < 10; i++){ // for(int j = 0; j < i; j++) // cout << dp[i][j] << " "; // cout << endl; // } }