POJ 3276 Face The Right Way【枚举】
2016-02-09 18:50
447 查看
题意:
N头牛站成一条线,分别朝向前后两个方向,机器可以使连续K头牛同时改变方向,要求所有牛最终朝向前方,问机器操作次数的最小值及此时的最小K值。分析:
第一眼看感觉是二分搜索K,再仔细读题,please help him determine the minimum value of K that minimizes the number of operations required by the machine to make all the cows face forward.
是在最小操作的基础上的最小K值,而操作数可达2N个,肯定不能搜索状态了,可以对K进行枚举,算出每次的操作数,进行比较。
直接暴力的话时间复杂度O(n3)过不了,必须进行优化,尽量扫描一遍就获得操作数。
因为是K个连续的一起转,即第i到i+k−1号牛要一起转,由于这次转动是由第i号牛引起的,就把这次转动体现在a[i]上,令a[i]=1,那么在遍历到第i+k−1号牛之前,i+k−1号牛所转动的次数就是∑i+k−2ia[i],遍历到第i+k−1号牛时,根据求出的转动次数及他本身的方向,判断是否需要转动,依次处理下去。最后判断剩余k−1头牛是否全部面向前方。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<map> using namespace std; const int maxn = 5005, INF =0x3fffffff; int s[maxn],a[maxn]; int N; int judge(int k) { memset(a, 0, sizeof(a)); int cnt = 0; int sum = 0; for(int i = 0; i < N - k + 1; i++){ if((s[i] + sum) % 2 == 1){ a[i] = 1; cnt++; } sum += a[i]; if(i-k+1>=0) sum -= a[i-k+1]; } for(int i = N - k +1; i < N; i++){ if((s[i] + sum) % 2 == 1){ return -1; } if(i-k+1>=0) sum -= a[i-k+1]; } return cnt; } int main (void) { map<char,int>m; m.insert(make_pair('B',1)); m.insert(make_pair('F',0)); scanf("%d", &N); char c; for(int i = 0; i < N;i++){ getchar(); c = getchar(); s[i] = m[c]; } int res = INF, k; for(int i = 1; i <= N;i++){ int ans = judge(i); if(ans == -1) continue; else if(ans < res){ res = ans; k = i; } } printf("%d %d\n", k, res); }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- 用单调栈解决最大连续矩形面积问题
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)
- POJ 1200 Crazy Search(简单哈希)
- 【高手回避】poj3268,一道很水的dijkstra算法题