您的位置:首页 > 其它

贪心和DP POJ2287 田忌赛马

2014-07-18 10:53 183 查看
题目大意:给出田忌和王的 N 匹马,安排赛马顺序使得得分最多,赢一场+200,输一场-200...

分析:我贪心了好久都是WA的= =.. 主要是没有想明白思路,怎样才能得到最大收益,总觉得像是DP,事实证明DP可以做,不过空间耗费大,时间比贪心慢10倍吧0.0

思路一:我们当前的最快的马比王的最快马慢的时候,显然,我们需要用最慢的马来和王最快的马比。

思路二:我们当前的最快的马比王的最快马快的时候,直接比...

思路三:我们当前的最快的马和王的最快马一样快的时候,我们这个时候需要比较一下我们最慢的马的价值:

1.我们最慢的马比王最慢的马快,直接比,获得最大的收益。

2.我们最慢的马比王最慢的马慢或者相等,那我们把最慢的马和王最快的马比,获得最大收益,注意判断我们最慢的马是否和王最快的马速度一样0.0、

代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[1200],b[1200];
bool vis[1200];
int main(){
int n;
while (~scanf("%d",&n),n){
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++) scanf("%d",&b[i]);
sort(a+1,a+1+n);
sort(b+1,b+1+n);
memset(vis,false,sizeof(vis));
int ans=0,cnt=0;
int l=1,r=n;
int k=1;
for (int i=n;i>=k&&l<=r;){
if (a[r]>b[i]) {
ans++;
r--;i--;
}
else {
if (a[l]>b[k]){
l++;k++;
ans++;
}
else {
if (a[l]<b[i]){
cnt++;l++;i--;
}
else {
l++;i--;
}
}
}
}
printf("%d\n",(ans-cnt)*200);
}
return 0;
}


DP思路:

DP的做法首先要构造DP的状态,要不断的尝试...

我们设 dp[i][j] 表示 进行到 第 i 场比赛,我们使用了 j 匹慢马获得的最大收益。

则 dp[i][j]=max(dp[i-1][j]+ score(a[i-j],b[i] , dp[i-1][j-1]+ score(a[n-j+1] , b[i] ));

代码如下:

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

bool cmp(int x,int y){
return x>y;
}
int score(int x,int y){
if (x>y) return 1;
if (x==y) return 0;
return -1;
}
int a[1200],b[1200],dp[1200][1200];
int main(){
int n;
while (scanf("%d",&n),n){
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++) scanf("%d",&b[i]);
sort(a+1,a+1+n,cmp);
sort(b+1,b+1+n,cmp);
memset(dp,-10000,sizeof(dp));
dp[0][0]=0;
for (int i=1;i<=n;i++){
for (int j=0;j<=n;j++){
if (j==0) dp[i][j]=max(dp[i][j],
dp[i-1][j]+score(a[i-j],b[i]));
else {
dp[i][j]=max(dp[i-1][j]+score(a[i-j],b[i]),
dp[i-1][j-1]+score(a[n-j+1],b[i]));
}
}
}
int ans=dp
[0];
for (int i=1;i<=n;i++)
if (ans<dp
[i]) ans=dp
[i];
printf("%d\n",ans*200);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: