Блог пользователя mamka

Автор mamka, история, 9 лет назад, По-русски

Может кто объяснить как решать? Буду очень благодарен

Теги 323
  • Проголосовать: нравится
  • +4
  • Проголосовать: не нравится

»
9 лет назад, # |
Rev. 3   Проголосовать: нравится +10 Проголосовать: не нравится

Для начала проанализируем задачу, можно заметить, что оптимально нам будет сначала просто подыматься по массиву, и достигнув значения, встречающегося чаще всего, "застыть" и прибавлять только его, и под конец снова продолжить подыматься. Проще будет понять картинкой:
1. Увеличим наш массив до размеров min(t*n,n*n). Обновим t, теперь t = max(0,t-n) — сколько раз повторится изначальный массив.
2. Для данного массива посчитаем dp[i] — длинна наибольшей неубывающей подпоследовательности заканчивающейся до или в i позиции. Это можно сделать за N^2 или за NlogN
3. Посчитаем cnt[] — сколько раз встречается каждое значение (От 0 до n-1).
4. Тогда ответом на задачу будетmax(dp[i]+cnt[i]*t+(dp[n-1]-dp[i])) = max(cnt[i]*t+maxdp) UPD: n = a.size()

И код:

        int n, t; cin >> n >> t;
	vector<ll> a(n); 
	fi(n) cin >> a[i];
	//1.
	fj(min(99, t - 1))
		fi(n)
			a.push_back(a[i]);
	t = max(0, t - 100);
	//2. DP
	vector<ll> dp(a.size(), 1);
	fi(a.size())
		for (int j = i - 1; j >= 0; j--)
			if (a[j] <= a[i]) dp[i] = max(dp[i], dp[j] + 1);
	ll maxdp = 0; fi(dp.size()) maxdp = max(dp[i], maxdp);
	//3. CNT
	vector<ll> cnt(400, 0);
	fi(n) cnt[a[i]]++;
	//4. ANS
	ll ans = 0;
	fi(a.size())
		ans = max(ans, cnt[a[i]] * t + maxdp);
	cout << ans << endl;

http://codeforces.net/contest/582/submission/13404900
Итоговая сложность (N^2)logN или N^4 в зависимости от алгоритма поиска наибольшей неубывающей подпоследовательности.