#90 C

來源:互聯網
上載者:User

problem link http://codeforces.com/contest/119/problem/C

A classic dp problem, even though I knew this I still spent much time on figuring out the solution.

As solving most dp problem, the difficult point is to find out the state transition equation.

Before working on the state transition equation, I need to realize what is the optimum condition, and the problem has

told me, the maximal possible amount of homework ( poor students. )

At first glance, I have found the first state: pick the Mth course at Nth day. 

But this is far from the complete state of dp, the key is how many homework of all courses should issue at N-1th day ?

Thanks to this forward thinking, I couldn't find the answer for about 2 hours.

The amount of homework which course i can issue is range from A[i] to B[i], and the problem has given me this data.

By backward thinking, for every possible course M in Nth day (some course can never be set to Nth day),

I need to know what is the maximal amount of homework when course M issue every possible amount of homework ( A[i] to B[i], the problem mentions that B[i] - A[i] <= 100, so enumeration is acceptable )

For example, I need to know the total amount of homework when course m in day n issues x homework, if that value is maximal, then I will pick these combination( day n, course m, issue x). according to the constraint given by the problem, there must be x - K or x/K homework issued at n-1 day by some other courses.

The above example is the key to find the state transition equation. ( But I have spent much time on expressing such example, stupid.. )

dp[n][m][x] = max{ every other courses m' | dp[n-1][m'][x-K] , dp[n-1][m'][x/K] } + x

Other constraint condition just some filters to state transition equation, no big deal.

#include <stdio.h>
#include <stdlib.h>

#define MAX_N 51
#define MAX_M 51
#define MAX_LEN 101

typedef struct path_info_st {
int m;
long long ht;
} path_info_st, *path_info_t;

long long A[MAX_M], B[MAX_M];
int C[MAX_M], L[MAX_M];
long long dp[MAX_N][MAX_M][MAX_LEN];
long long help1[MAX_M][MAX_LEN];
long long help2[MAX_M][MAX_LEN];
path_info_st path_data[MAX_N][MAX_M][MAX_LEN];
path_info_t path[MAX_N];
bool can_pick[MAX_N][MAX_M];
bool can_pick2[MAX_N][MAX_M][MAX_LEN];
int N, M, K;

int main() {
long long i, j, k, r, p, q, t, t1, t2, t3, t4, t5, t6;
scanf("%d %d %d", &N, &M, &K);
for( i=0;i<M;i++ )
scanf("%I64d %I64d %d", &(A[i]), &(B[i]), &(C[i]));
for( i=0;i<M;i++ )
L[i] = (int)(B[i] - A[i]);

for( i=0;i<M;i++ ) {
t = L[i];
t1 = A[i];

for( j=0;j<=t;j++ ) {
t2 = t1 + j;
help1[i][j] = t2 / K;
}

for( j=0;j<=t;j++ ) {
t2 = t1 + j;
help2[i][j] = t2 - K;
}
}

for( i=0;i<M;i++ ) {
t1 = A[i];
t = L[i];
for( j=0;j<=t;j++ )
dp[0][i][j] = t1 + j;

can_pick[0][i] = true;
}

for( i=1;i<N;i++ ) {
for( j=0;j<M;j++ ) {
t = L[j];
t1 = A[j];
for( k=0;k<M;k++ ) {
if( C[k] < C[j] && can_pick[i-1][k] ) {
t3 = A[k];
t4 = B[k];
for( r=0;r<=t;r++ ) {
t2 = t1 + r;
p = help1[j][r];
q = help2[j][r];
if( p >= t3 && p <= t4 && (t2 % K) == 0 ) {
t5 = dp[i][j][r];
t6 = dp[i-1][k][p-t3];
if( t6 > 0 && (0 == t5 || t5 < t2 + t6) ) { // t6 > 0 means there is a path to i-1 day set subject k and issues total t6 home task
dp[i][j][r] = t2 + t6;
path_data[i][j][r].m = k;
path_data[i][j][r].ht = p-t3;
can_pick[i][j] = true;
}
}
if( q >= t3 && q <= t4 ) {
t5 = dp[i][j][r];
t6 = dp[i-1][k][q-t3];
if( t6 > 0 && ( 0 == t5 || t5 < t2 + t6 ) ) { // t6 > 0 means there is a path to i-1 day set subject k and issues total t6 home task
dp[i][j][r] = t2 + t6;
path_data[i][j][r].m = k;
path_data[i][j][r].ht = q-t3;
can_pick[i][j] = true;
}
}
}
}
}
}
}

k = 0;
for( i=0;i<M;i++ ) {
t = L[i];
for( j=0;j<=t;j++ ) {
t2 = dp[N-1][i][j];
if( k < t2 ) {
k = t2; t3 = i; t4 = j;
}
}
}

if( 0 == k ) {
printf("NO\n");
return 0;
}

k = 0, i = 1;
printf("YES\n");
if( N > 1 ) {
path_info_t pi = &(path_data[N-1][t3][t4]);
for( i=1;i<N-1;i++ ) {
path[k++] = pi;
pi = &(path_data[N-i-1][pi->m][pi->ht]);
}
path[k++] = pi;

for( i=k-1;i>=0;i-- )
printf("%d %I64d\n", (int)(path[i]->m + 1), (path[i]->ht + A[path[i]->m]));
}
printf("%d %I64d\n", (int)(t3 + 1), (t4 + A[t3]));

return 0;
}

The most disgusting part of my code is recording the path info, and use it for backward tracing.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.