标签:
uva 1444
Description
You are in a library equipped with bookracks that move on rails. There are many parallel rails, i.e., the bookracks are organized in several rows, see figure:
To borrow a book, you have to find the librarian, who seems to hide on the opposite side of the bookracks. Your task then is to move the racks along the rails so that a passage forms. Each rack has a certain integer width, and can be safely positioned at any integer point along the rail. (A rack does not block in a non-integer position and could accidentally move in either direction). The racks in a single row need not be contiguous -- there can be arbitrary (though integer) space between two successive bookracks. A passage is formed at position k if there is no bookrack in the interval (k, k + 1) in any row (somehow you don‘t like the idea of trying to find a more sophisticated passage in this maze.)
Moving a rack requires a certain amount of efflort on your part: moving it in either direction costs 1. This cost does not depend on the distance of the shift, which can be explained by a well known fact that static friction is considerably higher than kinetic friction. Still, you are here to borrow a book, not to work out, so you would like to form a passage (at any position) with as little efflort as possible.
Two space separated integers R and L(1R, 1L106) are given in the first line of an input instance. They denote the number of rows and the width of each and every row, respectively. Then R lines with rows descriptions follow. Each such line starts with an integer ni, followed by ni integers ai, 1, ai, 2,...ai, ni, all separated by single spaces. Number ai, j denotes either the width of a bookrack when ai, j > 0or a unit of empty space when ai, j = 0. Note that for any row i,ai, j equals L minus the number of ai, j that are equal to zero. You may assume that n1 + n2 + ... + nR2*107. Moreover, there will be at least one 0 in the description of each row, which means that creating a passage is always possible.
In the first line, your program should output the minimum cost of making a passage through the bookracks. In the second line, it should print out the increasing sequence of all the positions at which a minimum cost passage can be formed.
1 4 10 8 1 2 1 0 1 2 0 1 7 2 2 2 1 0 1 0 6 1 3 2 0 2 1 7 2 1 2 0 2 1 0
3 8 9
题意:从上面到下面需要通过很多行,每一行都有书架或者空格,只有空格才能通过,问你最少需要移动多少书架才能达到终点
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=1e6+10; int g[maxn],can[maxn],zero[maxn],pos[maxn],a[maxn],cost[maxn]; int N,H; void Init() { int n; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; fill(cost,cost+maxn,-1); int ze=0,now=0; for(int i=0;i<n;i++) { if(a[i]==0) { zero[ze++]=i; can[now++]++; } else { now+=a[i]; int k=min(ze,a[i]);//空格长度与待移动书架长度,最多也只能移动空格位那么长 for(int j=1;j<=k;j++) { cost[now-j]=i-zero[ze-j]-(j-1);//只移j个,计算给(now-j)腾出空位需付代价 g[now-j]+=cost[now-j];//cost只是这一行的代价,总计用g(i) can[now-j]++;//那么(now-j) 这个位置也可以通行了 } } } reverse(a,a+n); //开始从右往左移 now--;ze=0; //ze赋值为零!!!!!代表现在还没有看到可以直接通过的位置 for(int i=0;i<n;i++) { if(a[i]==0) { zero[ze++]=i; now--; } else { now-=a[i]; int c=min(a[i],ze); for(int j=1;j<=c;j++) { if(cost[now+j]==-1) { cost[now+j]=i-zero[ze-j]-(j-1); g[now+j]+=cost[now+j]; can[now+j]++; } else { int cc=i-zero[ze-j]-(j-1); g[now+j]+=min(0,cc-zero[now+j]); } } } } } void Print() //只要满足最小移动数的列举,其余就算可以通过也不要 { int ans=1e9; int cnt=0; for(int i=0;i<H;i++) { if(can[i]==N) { if(ans>g[i]) { ans=g[i]; cnt=0; pos[cnt++]=i; } else if(ans==g[i]) pos[cnt++]=i; } } cout<<ans<<endl; for(int i=0;i<cnt;i++) cout<<pos[i]<<" "; puts(""); } int main() { int T; cin>>T; while(T--) { memset(can,0,sizeof(can)); //一定要清零 memset(cost,0,sizeof(cost)); memset(pos,0,sizeof(pos)); memset(g,0,sizeof(g)); //一定要清零 cin>>N>>H; for(int i=0;i<N;i++) Init(); Print(); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zsyacm666666/p/4915155.html