Cod sursa(job #172580)

Utilizator sims_glAlexandru Simion sims_gl Data 6 aprilie 2008 16:27:43
Problema Vanatoare Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <stdio.h>

#define nm 20
#define mm 300000
#define inf 1000000000

int n, T, a[nm], b[nm], v[nm], conf, c[mm], crt, sol[mm][nm];

long long cmmdc(long long a, long long b)
{
	if (b == 0)
		return a;
	return cmmdc(b, a % b);
}

void go1(int pos)
{
	if (pos > n) {
		long long sa = a[v[1]], sb = b[v[1]];

		for (int i = 2; i <= v[0] && sa >= 0; ++i) {
			long long ta = a[v[i]];

			while (sa != ta) {
				if (sa < ta)
					sa += sb;
				else
					ta += b[v[i]];

				if (sa > T || ta > T) {sa = -1; break;}
			}

			if (sb <= T)
				sb = sb * (b[v[i]] / cmmdc(sb, b[v[i]]));
			
			if (sb > T)
				sb = T + 1;
		}

		c[conf] = sa;
	} else {
		conf *= 2;
		go1(pos + 1);
		++conf;
		v[++v[0]] = pos;
		go1(pos + 1);
		--v[0];
		conf /= 2;
	}	
}

void go2(int pos)
{
	if (pos > n) {
		if (c[conf] != -1 && c[crt - conf] != -1 && sol[crt][0] > sol[conf][0] + sol[crt - conf][0]) {
			sol[crt][0] = sol[conf][0] + sol[crt - conf][0];

			for (int i = 1; i <= sol[conf][0]; ++i)
				sol[crt][i] = sol[conf][i];

			for (int i = 1; i <= sol[crt - conf][0]; ++i)
				sol[crt][sol[conf][0] + i] = sol[crt - conf][i];
		}
	} else {
		conf *= 2;
		go2(pos + 1);
		
		if (v[pos]) {
			++conf;
			go2(pos + 1);
		}

		conf /= 2;
	}
}

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

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

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

	go1(1);

	for (crt = 1; crt < (1 << n); ++crt) {
		if (c[crt] > -1) {
			sol[crt][0] = 1;
			sol[crt][1] = c[crt];
		} else {
			sol[crt][0] = inf;

			for (int i = n, tmp = crt; i; --i, tmp /= 2)
				v[i] = tmp % 2;

			go2(1);
		}
	}

	crt = (1 << n) - 1;

	printf("%d\n", sol[crt][0]);

	for (int i = 1; i <= sol[crt][0]; ++i)
		printf("%d ", sol[crt][i]);
	printf("\n");

	return 0;
}