题目:http://poj.org/problem?id=3150
题意:给出 n 个数构成一个环,给出 m d k,每一个数从它的两边(连续的)各找 d 个数和这个数相加 再取余m后更新这个数,问 k 次操作后,输出新的n 个数的顺序。
不知道怎么优化,看了别人的解析 http://hi.baidu.com/moon_1st/item/0381d80a85fd258a3d42e2f0,循环矩阵经过 k 次幂后仍然是循环矩阵,而且有 a[i][j] = a[i - 1][j - 1]成立,这样转移矩阵的下一列就可以由这一列转换过去,降低复杂度
题目:http://poj.org/problem?id=2976
0/1分数规划,按照二分的方法 从 0 到 1 查找, 对于每一对数(ai,bi),计算 ai-mid*bi 的大小。然后进行排序,选择最大的n-k个数字,求出他们的和,如果总和大于0,说明结果偏小,所以left = mid 否则 right = mid
View Code
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <math.h> 6 #define esp 0.000001 7 #define N 1010 8 9 using namespace std; 10 11 int a[N],b[N]; 12 double t[N]; 13 int main() 14 { 15 int i; 16 int n,k; 17 while(scanf("%d%d",&n,&k) && (n + k)) 18 { 19 for(i = 0; i < n; i++) 20 scanf("%d",&a[i]); 21 for(i = 0; i < n; i++) 22 scanf("%d",&b[i]); 23 double left,right,mid; 24 left = 0; 25 right = 1; 26 while(fabs(left - right) >= esp) 27 { 28 mid = (left + right) / 2; 29 for(i = 0; i < n; i++) 30 t[i] = a[i] - mid * b[i]; 31 sort(t,t + n); 32 double sum = 0; 33 for(i = k; i < n; i++) 34 sum += t[i]; 35 if(sum > 0) left = mid; 36 else right = mid; 37 } 38 //mid *= 100; 39 left *= 100; 40 printf("%.0lf\n",left); 41 } 42 return 0; 43 }