Qruplaşdırma vəzifəsi#1525

Qruplaşdırma vəzifəsi (Həll təhlili)

Qoy a_1, a_2, ..., a_n — verilmiş ədəd olsun. F_{ik}~(i \ge k) ifadəsi ilə a_1, ..., a_i ilk ədəd arasından seçilmiş mümkün olan bütün ədədlərin hasilatlarının cəmini təyin edək. Aşağıdakı F_{ik} dəyərləri cədvəlini quraq:

Dörd ədəd üçün əldə edirik:

Aşağıdakı rekurent bərabərliklər yerinə yetirilir:

F_{i1} = F_{(i-1)1} + a_i\\ F_{ii} = F_{(i-1) (i-1)} \cdot a_i, 1 \le i \le n \\ F_{ik} = F_{(i-1)k} + F_{(i-1) (k-1)} \cdot a_i, 1 \le i \le n, 1 < k < i

Məsələn,

Hər bir növbəti xəttin dəyərləri əvvəlki xəttin dəyərlərinə əsasən hesablandığından, məlumatları saxlamaq üçün ölçüdə bir xətti massiv kifayətdir. -ci xəttin dəyərlərini yenidən sayma əməliyyatını sondan başlamaqla yerinə yetirmək lazımdır: öncə F_{ii} hesablanır, sonrakı F_{i(i-1)} və sairə F_{i1}-ə qədər. Bütün hesablamalar modulu üzrə aparılmalıdır.

Məsələn,

Birinci testi nəzərdən keçirək. İki cədvəl düzəldək: birincisində hesablamalar moduldan olmadan aparılır, ikincisində isə m = 10 modulu üzrə.

Məsələn,

Cavab ikinci cədvəlin dördüncü xəttindəki maksimum dəyərdir.

Alqoritmin həyata keçirilməsi

F_{ik} dəyərlərinin yenidən hesablanacağı xətti massiv elan edək.

long long d[1000];

Ədədlərin sayını və dəyərini daxil edirik. Hər bir giriş testi üçün əvvəlcədən massivini sıfırlayırıq. İlk ədəd a_1-i -a əlavə edirik.

while (scanf("%lld %lld",&n,&m), n + m > 0)
{
  memset(d,0,sizeof(d));
  scanf("%lld",&d[0]);

Sonra x = a_{i+1}~(1 \le i < n) dəyərini daxil edirik və yuxarıda verilmiş rekursiya formullarına görə F_{ik} dəyərlərini k = i, i - 1, ..., 1 üçün yenidən hesablayırıq. Bütün hesablamalar modulu üzrə aparılır.

  for (i = 1; i < n; i++)
  {
    scanf("%lld",&x);
    d[i] = (d[i-1] * x) % m; 

    for (j = i - 1; j > 0; j--)
      d[j] = (d[j-1] * x + d[j]) % m;

    d[0] = (d[0] + x) % m;
  }

massivinin elementləri arasında maksimum dəyəri tapırıq və onu dəyişəninə saxlayırıq.

  res = 0;
  for (i = 0; i < n; i++)	   
    if (d[i] > res) res = d[i];

Nəticəni çıxarırıq.

  printf("%lld\n",res);
}