15 Eylül 2014 Pazartesi

Tile Exchanging

Tile Exchanging [Ray Li]

Çiftçi John ahırının zeminindeki taşları yenilemek istemektedir. John ahırının alanını bilmeden N tane kare şeklinde taş almıştır. Bu taşların sırayıla bir kenarlarının uzunluğu A_1...A_N dir. Ahırının tabanının alanının M metrekare olduğunu öğrenen John zeminini kaplamak için elindeki
taşların alanının toplamını M yapmaya karar vermiştir.

Çiftçi John markete gider ve elindeki taşları değiştirmek ister market sahibi: her bir A_i büyüklüğündeki taşını B_i büyüklüğündeki taş ile değiştiririm ancak |A_i-B_i|*|A_i-B_i| kadar maliyeti olur der.

Sizden istenen N,M ve A_i dizisi veriliğinde alanı kaplamak için gereken minimum maliyeti bulmanızdır.Eğer toplamını M yapmanız imkansızsa -1 yazdırınız.

SORU KODU: tilechng

GİRDİ BİÇİMİ:

* Satır 1: Boşlukla ayrılmış iki sayı, N (1<=N<=10) and M (1<=M<=10,000).

* Satır 2..1+N: Her bir satırda A_1 den A_N'e kadar olan diziyi temsil eden N sayı yer alacaktır.
        (1<=A_i<=100).

ÖRNEK GİRDİ (file tilechng.in):

3 6
3
3
1

GİRDİ AÇIKLAMASI:

3 tane taş vardır boyutları sırasıyla 3x3, 3x3 ve 1x1 dir. Amacımız bunların toplamını M yapacak şekilde değiştirmektir.

ÇIKTI BİÇİMİ:

* Line 1: Toplamı M yapmak için gereken minimum maliyet eğer çözüm yoksa -1 yazdırınız.

ÖRNEK ÇIKTI (file tilechng.out):

5

ÇIKTI AÇIKLAMASI:

3x3 lerin bir tanesi 2x2 ile değiştirilir ve 3x3 lerin bir tanesi 1x1 ile değitririlir. Toplam mailiyet 1+4=5 olur.

--------------------------------------------------------------------------------------------------------------------------
Gönderilebilecek link:http://usaco.org/index.php?page=nov11problems
Test dataları:http://usaco.org/current/data/tilechng.zip
--------------------------------------------------------------------------------------------------------------------------


Çözüm Metni

Problem dinamik programlama ile çözülebilir. Best[i][j] sunu temsil etsin. 1 den j ye kadar olan taslari degistirerek i alani elde etmek icin minimum gerekli maliyet. Baslangic durumu olarak
best[0][0]=0 ve best[i>0][0]=sonsuz. Diger durumlar icin recursive bir cozum gelistirebiliriz.

best[i][j]=0<=k<=sqrt(i) icin min( (k-A[j])^2 + best[i-k*k][j-1] );

k j tasinin k ile degistirilmesini temsil etmektedir. Best[i][j] nin degeri A_j hangi k degeriyle degistirilirse minimum olur bunu bulup saklamaktadir. k yeni alinacak tasin bir kenar uzunlugunu belirtmektedir (k-A[j])^2 degisim maliyetini ve i-k*k 1...j-1 araligindan elde edilmesi gereken toplam alani ve best[i-k*k][j] ise bu alani 1...j-1 taslari degistirilerek elde edilmesinin minimum maliyetini saklamaktadir.

Calisma zamani hesaplamasi k*k<=i<=M ve j<=N oldugu icin 10*100*10000=10 milyon bu da demektir ki cozumumuz 1 sn de calisir.

Not: 0 boyutlu kareler olabilmektedir kod a bunu dahil etmeliyiz 100 alabilmek icin.

--------------------------------------------------------------------------------------------------------------------------

Çözüm kodu:

#include <stdio.h>

#define MAX_M 10000
#define MAX_N 10
#define INF 1000000000

int best[MAX_M+1][MAX_N+1];
int A[MAX_M+1];

int main(void)
{
  int M, N, i, j, k;

  freopen ("tilechng.in", "r", stdin);
  freopen ("tilechng.out", "w", stdout);

  scanf ("%d %d", &N, &M);
  for (i=1; i<=N; i++)
    scanf ("%d", &A[i]);

  for (i=1; i<=M; i++)
    best[i][0] = INF;

  for (j=1; j<=N; j++)
    for (i=0; i<=M; i++) {
      best[i][j] = INF;
      for (k=1; k*k<=i; k++)
      if ((A[j]-k)*(A[j]-k) + best[i-k*k][j-1] < best[i][j])
        best[i][j] = (A[j]-k)*(A[j]-k) + best[i-k*k][j-1];
    }

  if (best[M][N]==INF)
    printf ("-1\n");
  else
    printf ("%d\n", best[M][N]);

  return 0;
}

Hiç yorum yok:

Yorum Gönder