cqx에서 온 dp신제.
제목은shtsc2010, 무도회에서 유래했다.제목은 n명의 남자의 키를 B[i], n명의 여자의 키를 G[i]로 정하고 몇 가지 조합 방식을 구하여 많은 k의 댄서 파트너 사이에서 여자가 남자보다 높게 만든다는 뜻이다.
cqx는 두 가지 dp방식이 있는데, 나는 첫 번째 방식에 따라 dp를 한다.
현재 B[i], G[i]의 승차 순서를 정하고 상태 f[i, j]를 남녀 각 전 i개인으로 정의한다. 여자가 남자보다 키가 큰 j의 댄서 파트너 수는 k의 방안 수이다.
명령 Gk = min {k|1 <=k <=i, G[Gk]> B[i]}, Bk = min {k|1 <=k <=i, B[Bk]>= G[i]}, 하나는 등호가 있는지 주의해라.
먼저 쓰기 전이 방정식: f[i][j] = f[i-1] [j-(B[i] < G[i])] + (i-j + Bk - Gk)* f[i-1] [j-1] + (j-Bk + Gk)* f[i-1] [j].못 알아보겠어?괜찮아, 이 문제는 어려우면 옮기기 어려워, 이 옮기는 것도 하나의 경지가 되기 어려워.
밤새 이동을 미루며 몇 개의 양을 헤매다.미치겠네.
오늘 아침에 오자마자 계속 밀고 옮겼는데, 마침내 내 AC에 의해 떨어졌다.
이동은 다음과 같습니다.
1. B[i]와 G[i]를 짝짓기;
이때 원래의 것은 모두 j-(B[i]
3. G[k]>B[i]로 하여금 같은 이치로 얻을 수 있다. 여자가 남자보다 높은 대수는 1->2이기 때문에 f[i-1][j-1]에서 옮기면 k는 모두 i-Gk개가 있다.
4. 만약에 B[k]
5. 만약에 G[k]위에서 말한 것을 종합하면 모두 합치면 f[i][j]의 전이 표현식을 얻을 수 있다.
cqx가 너무 부도덕해서 고정(사실은 두 번째 방법을 끊기 위해서)까지 써야 하기 때문에 머리가 어지럽고 사지에 힘이 없어서 짜증나 죽겠어요.
마지막으로 예제에 따라 코드를 붙입니다.
#include
#include
#include
#define maxlen 100
#define maxn 205
#define base 1000000
typedef int bn[maxlen];
bn buf;
bn dp[maxn][maxn];
int B[maxn];
int G[maxn];
void add (bn p, bn q, int k)
{
if (!k || !q[0] || !q[q[0]]) return;
bn x;
int i;
memset (x, 0, sizeof (x));
x[0] = p[0] > q[0] ? p[0] : q[0];
for (i = 1; i <= x[0]; ++i)
x[i] = p[i] + q[i] * k;
for (i = 1; i <= x[0]; ++i)
if (x[i] >= base)
x[i + 1] += x[i] / base, x[i] %= base;
if (x[x[0] + 1]) ++x[0];
memcpy (p, x, sizeof (bn));
}
int cmper (const void *i, const void *j)
{
return *(int *)i - *(int *)j;
}
int main()
{
FILE *fin = fopen ("ball.in" , "r");
FILE *fout = fopen ("ball.out", "w");
int n, k, Gk = 0, Bk = 0, i, j;
bn ans;
fscanf (fin, "%d%d", &n, &k);
for (i = 1; i <= n; ++i)
fscanf (fin, "%d", &B[i]);
for (i = 1; i <= n; ++i)
fscanf (fin, "%d", &G[i]);
qsort (B + 1, n, sizeof (B[0]), cmper);
qsort (G + 1, n, sizeof (G[0]), cmper);
dp[0][0][0] = 1, dp[0][0][1] = 1;
for (i = 1; i <= n; ++i)
{
for (; G[Gk] <= B[i] && Gk < i; ++Gk);
for (; B[Bk] < G[i] && Bk < i; ++Bk);
for (j = i - Gk; j <= Bk; ++j)
{
memcpy (dp[i][j], dp[i - 1][j - (B[i] < G[i])], sizeof (bn));
add (dp[i][j], dp[i - 1][j - 1], i - j + Bk - Gk);
add (dp[i][j], dp[i - 1][j ], j - Bk + Gk);
}
}
memset (ans, 0, sizeof (ans));
for (i = 0; i <= k; ++i)
add (ans, dp[n][i], 1);
fprintf (fout, "%d", ans[ans[0]]);
for (; --ans[0] > 0; )
fprintf (fout, "%06d", ans[ans[0]]);
fclose (fin);
fclose (fout);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C에서 파일 입/출력저장 및 , 우리는 파일 유형을 가리키는 구조 포인터를 사용합니다 - FILE. fopen() 함수는 기존 파일을 열거나 새 파일을 만드는 데 사용됩니다. 여기서 fp는 열린(또는 생성된) 파일에 대한 참조를 보유할...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.