题目一:设原始数组为a[],初始值均为0,我们对数列a[]进行两种操作:
(1)对某些数加1 (2)对所有的数乘2
问至少经过多少次操作达到给定的序列。
分析:先对给定的数组a[]中的奇数减1,然后对所有的数除以2,然后反复进行此操作,直到所有的数为0.
题目二: http://acm.hdu.edu.cn/showproblem.php?pid=2037
分析:先按节目的结束时间排序,越早结束的节目当然要先看,按照这样的方法处理。
题目三:http://acm.hust.edu.cn/problem.php?id=1618
题意:把1~n*n之间的数填入n*n的矩阵,使得所有两两相邻元素和的最大值最小,求这个最小值。例如n = 2时
1 4
3 2
这种方式形成的最小值为6,其余的填法形成的都比这个值大。
分析:这个最小值为:n^2 + n/2 + 1,证明无。
题目四:http://codeforces.com/contest/346/problem/C
题意:给两个数字a和b,a>=b,再给一个数组x[],现在我们要把a变成b,只能进行两种操作:
(1)把a自减1 (2)把a减去a%x[i]
现在求最小的步数把a变为b。
分析:本题是很明显的贪心算法。当然在开始之前我们首先要对数组x[]去重,当然这个用sort排一下序,然后用STL的unique,然后就是每次找a%x[i]的最大值,然后还要保证每次a减了之后要大于等于b。
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> using namespace std; const int N = 100005; int x[N]; int main() { int n,a,b; while(scanf("%d",&n)!=EOF) { for(int i=0; i<n; i++) scanf("%d",&x[i]); scanf("%d%d",&a,&b); sort(x,x+n); n = unique(x,x+n)-x; int ans = 0; while(a > b) { int maxval = 1; for(int i=0; i<n; i++) { if(a - a%x[i] >= b) maxval = max(maxval,a%x[i]); } a -= maxval; while(n && a-a%x[n-1] < b) n--; ans++; } printf("%d\n",ans); } return 0; }