poj2287

题意:田忌赛马,两人各n匹马,每匹马有个速度,快的能胜慢的,赢一场赚200,输一场输200,平一场不赚钱。每次大王先出马,然后田忌再出马应对。问田忌最多赢赚多少钱。

分析:可以用贪心,但是这里说一下dp的做法。

dp,O(n^2)

f[i][j]表示用他的前i匹马与对方的前j匹马,赢的得200,平的不得,其余一律输200,最多能多少钱。

if (h1[i] > h2[j])
f[i][j] = max(f[i - 1][j - 1] + 200,f[i - 1][j] - 200, f[i][j - 1] - 200);
else if (h1[i] == h2[j])
f[i][j] = max(f[i - 1][j - 1],f[i - 1][j] - 200, f[i][j - 1] - 200);
else
f[i][j] = max(f[i - 1][j] - 200, f[i][j - 1] - 200);

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

#define maxn 1005

int h1[maxn], h2[maxn];
int f[maxn][maxn];

int main()
{
// freopen("t.txt", "r", stdin);
int n;
while (scanf( " %d " , & n), n)
{
for ( int i = 1 ; i <= n; i ++ )
scanf(
" %d " , & h1[i]);
for ( int i = 1 ; i <= n; i ++ )
scanf(
" %d " , & h2[i]);
sort(h1
+ 1 , h1 + n + 1 );
sort(h2
+ 1 , h2 + n + 1 );
f[
0 ][ 0 ] = 0 ;
f[
0 ][ 1 ] = 0 ;
f[
1 ][ 0 ] = 0 ;
for ( int i = 1 ; i <= n; i ++ )
for ( int j = 1 ; j <= n; j ++ )
{
if (h1[i] > h2[j])
f[i][j]
= max(f[i - 1 ][j - 1 ] + 200 ,
max(f[i
- 1 ][j] - 200 , f[i][j - 1 ] - 200 ));
else if (h1[i] == h2[j])
f[i][j]
= max(f[i - 1 ][j - 1 ],
max(f[i
- 1 ][j] - 200 , f[i][j - 1 ] - 200 ));
else
f[i][j]
= max(f[i - 1 ][j] - 200 , f[i][j - 1 ] - 200 );
}
printf(
" %d\n " , f[n][n]);
}
return 0 ;
}

你可能感兴趣的:(poj)