Cod sursa(job #163610)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 22 martie 2008 14:49:09
Problema Vanatoare Scor 50
Compilator cpp Status done
Runda preONI 2008, Runda Finala, Clasele 11-12 Marime 1.76 kb
#include <stdio.h>
#include <string>

#define maxn 16
#define maxx 1<<16
#define inf 2000000100

int n,m,l;
int a[maxn],b[maxn],timp[maxn];
int s[maxn];
int d[maxx],from[maxx];
char c[maxx];

int GCD(int a,int b)
{
	while (b)
	{
		int aux = a%b;
		a = b;
		b = aux;
	}

	return a;
}

int main()
{
	freopen("vanatoare.in","r",stdin);
	freopen("vanatoare.out","w",stdout);

	scanf("%d %d ",&n,&m);

	int i,j,k,poz,best,stare,found;
	int smen,aux,startmax;
	long long T;

	for (i=0; i<n; i++) scanf("%d %d ",&b[i],&a[i]);

	for (i=0; i<n; i++) timp[i] = (m-b[i]) / a[i];

	memset(d,-1,sizeof(d));

	for (i=1; i<1<<n; i++)
	{
		best = inf;
		poz = l = smen = startmax = 0;

		for (j=0; j<n; j++) 
			if (i&(1<<j))
			{
				if (timp[j] < best)
				{
					best = timp[j];
					poz = j;
				}
				if (b[j] > startmax) startmax = b[j];
				s[l++] = j;
			}

		for (j=0;j<l;j++)
			for (k=j+1;k<l;k++)
			{
				aux = GCD(a[s[j]],a[s[k]]);
				if (b[s[j]]%aux != b[s[k]]%aux) smen = 1;
			}

		for (j=0;j<l;j++)
		{
			aux = i^(1<<s[j]);
			if (aux && d[aux] == -1) smen = 1;
			if (d[aux] > startmax) startmax = d[aux];
		}

		if (smen) continue;

		for (T = b[poz]; T<startmax && T<=m; T+= a[poz]);

		for (; T<=m; T += a[poz]) 
		{
			found = 0;
			for (k=0; k<l && !found; k++)
				if ((T-b[s[k]])%a[s[k]] != 0) found = 1;

			if (!found)
			{
				d[i] = T;
				break;
			}
		}
	}

	for (i=1;i<1<<n;i++)
	{
		c[i] = n+1;

		l = 0;
        for (j=0;j<n;j++)
			if (i&(1<<j)) s[l++] = j;

		for (j=1;j<1<<l;j++)
		{
			stare = 0;
			for (k=0;k<l;k++) 
				if (j&(1<<k)) stare += 1<<s[k];

			if (d[stare]!=-1 && c[i^stare]+1<c[i]) 
			{
				c[i] = c[i^stare]+1;
				from[i] = stare;
			}
		}
	}

	printf("%d\n",c[(1<<n)-1]);

	for (i=(1<<n)-1; i; i^=from[i]) printf("%d ",d[from[i]]);
	printf("\n");

	return 0;
}