您的位置:首页 > 其它

poj 1015 DP

2014-03-06 21:29 162 查看
T_T......

都是泪啊。。。。。

一开是看数据不多 直接能找出所有状态,然后就是dp【N】【M】【k】。。。。一开是的时候这个表示的是前N个找出M个能获得的从D-P的值能否为k,然后发现不最后不能递归求找出D+P最大的状态。。。。。最后想用dp【N】【M】【k】表示前N个找出M个能获得的从D-P的值为k时所能获得的最大的D+P值,如果不存在就用MAX表示。。。这样两中状态都有了。。。。注意下不能用-1来表示不存在!!!

代码比较搓,。。因为调试了一晚上。。。。。。。orz。。。能过就行。。。。。

AC代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

#define MAX 0x3f3f3f3f

struct Node{
int p, d;
int id;
int sub;
int sum;
};

Node node[210];
int dp[210][21][810];
int N, M;
int ansnum[2][22], ansP[2], ansD[2];

int cmp( const void *a, const void *b ){
if( ( ((Node*)a)->p + ((Node*)a)->d ) != ( ((Node*)b)->p + ((Node*)b)->d ) )
return ((Node*)a)->p + ((Node*)a)->d - ( ((Node*)b)->p + ((Node*)b)->d );
return ((Node*)b)->id - ((Node*)a)->id;
}

int cmpp( const void *a, const void *b ){
return *((int*)a) - *((int*)b);
}

int DFS( int n, int m, int val, int k ){
if( m == 0 ){
return 1;
}
int temp = val-node
.sub;
if( temp >=0 && temp <= 800 && dp[n-1][m-1][val-node
.sub] != MAX && dp[n-1][m-1][val-node
.sub] == dp
[m][val] - node
.sum ){
ansnum[k][m] = node
.id;
//      cout << node
.id << "***";
ansP[k] += node
.p;
ansD[k] += node
.d;
if( DFS( n - 1, m - 1, val-node
.sub, k ) ){
return 1;
}
}else{
if( DFS( n - 1, m, val, k ) ){
return 0;
}
}
return 0;
}

int main(){
int Case = 1;
while( scanf( "%d%d", &N, &M ) && !( N == 0 && M == 0 ) ){
for( int i = 1; i <= N; i++ ){
scanf( "%d%d", &node[i].p, &node[i].d );
node[i].id = i;
node[i].sub = node[i].p - node[i].d;
node[i].sum = node[i].p + node[i].d;
}
qsort( &node[1], N, sizeof( Node ), cmp );
memset( dp, 0x3f, sizeof( dp ) );
dp[0][0][400] = 0;
for( int i = 1; i <= N; i++ ){
for( int j = 0; j <= i && j <= M; j++ ){
for( int k = 0; k <= 800; k++ ){
if( i - 1 >= j && dp[i-1][j][k] != MAX ){
if( dp[i][j][k] != MAX ){
dp[i][j][k] = max( dp[i][j][k], dp[i-1][j][k] );
}else{
dp[i][j][k] = dp[i-1][j][k];
}

}
if( j - 1 >= 0 && k - node[i].sub >= 0 && k - node[i].sub <= 800 && dp[i-1][j-1][k-node[i].sub] != MAX ){
if( dp[i][j][k] != MAX ){
dp[i][j][k] = max( dp[i][j][k], dp[i-1][j-1][k-node[i].sub] + node[i].sum );
}else{
dp[i][j][k] = dp[i-1][j-1][k-node[i].sub] + node[i].sum;
}
}
}
}
}
int temp1, temp2;
for( temp1 = 400; temp1 <= 800; temp1++ ){
if( dp
[M][temp1] != MAX ){
break;
}
}
for( temp2 = 400; temp2 >= 0; temp2-- ){
if( dp
[M][temp2] != MAX ){
break;
}
}
ansP[0] = ansD[0] = 0;
if( temp1 >= 400 && temp1 <= 800 ){
DFS( N, M, temp1, 0 );
}
ansP[1] = ansD[1] = 0;
if( temp2 >= 0 && temp2 <= 400 ){
DFS( N, M, temp2, 1 );
}
qsort( &ansnum[0][1], M, sizeof( int ), cmpp );
qsort( &ansnum[1][1], M, sizeof( int ), cmpp );
int temp;
if( abs( temp1 - 400 ) < abs( temp2 - 400 ) ){
temp = 0;
}else if( abs( temp1 - 400 ) > abs( temp2 - 400 ) ){
temp = 1;
}else{
temp = ( ansP[0] + ansD[0] > ansP[1] + ansD[1] ) ? 0 : 1;
}
printf( "Jury #%d\nBest jury has value %d for prosecution and value %d for defence: \n", Case++, ansP[temp], ansD[temp] );
for( int i = 1; i <= M; i++ ){
cout << " " << ansnum[temp][i];
}
cout << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: