题目一:设原始数组为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;
}