P2587 [ZJOI2008]泡泡堂
分析:
对于这种通过合理分配来获得较高分的问题,有dp和贪心两种方法。
贪心在考场上写有点悬,最好对拍来及时检查贪心策略是否正确。
这道题的贪心策略是:(序号有优先顺序)
1. 弱的赢弱的
2. 强的赢强的
3. 两个都不行,就让弱的送强的(同时判断一下能否平局)
同时,我方最坏就是对方最优,总的减去对方最优即可。
#include<bits/stdc++.h> using namespace std; #define ri register int #define N 100005 int n,a[N],b[N]; int work() { int l1=1,r1=n,l2=1,r2=n,ans=0; //贪心策略:如果最弱的能赢最弱的,就直接赢,否则就考虑最强的能不能赢最强的,再不行才考虑用最弱的送给最强的,记得判断一下是否能平局 while(l1<=r1 && l2<=r2){ if(a[l1]>b[l2]) ans+=2,l1++,l2++; else if(a[r1]>b[r2]) ans+=2,r2--,r1--; else ans+=(a[l1]==b[r2]),l1++,r2--; } return ans; } int main() { scanf("%d",&n); for(ri i=1;i<=n;++i) scanf("%d",&a[i]);//me for(ri i=1;i<=n;++i) scanf("%d",&b[i]); sort(a+1,a+1+n); sort(b+1,b+1+n); int anss=work(); swap(a,b); printf("%d %d",anss,2*n-work()); } /* 2 1 3 2 4 8 4 1 0 7 8 3 5 5 4 8 0 3 4 2 5 7 4 1 2 2 9 9 3 2 4 3 2 9 8 4 7 2 */
P1650 田忌赛马
分析:
这道题和上一道一样,策略同样是:弱打弱,强打强,弱送强。
#include<bits/stdc++.h> using namespace std; #define ri register int #define N 100005 int n,a[N],b[N]; void work() { int l1=1,r1=n,l2=1,r2=n,ans=0; for(ri i=1;i<=n;++i){ if(a[l1]>b[l2]) ans++,l1++,l2++; else if(a[r1]>b[r2]) ans++,r1--,r2--; else { if(a[l1]>b[r2]) ans++; else if(a[l1]<b[r2])ans--; l1++; r2--; } } printf("%d\n",ans*200); } int main() { scanf("%d",&n); for(ri i=1;i<=n;++i) scanf("%d",&a[i]);//me for(ri i=1;i<=n;++i) scanf("%d",&b[i]); sort(a+1,a+1+n); sort(b+1,b+1+n); work(); return 0; } /* WA: 5 5 1 2 8 3 5 0 6 5 2 */
(l, r 指针不要打反了。。。)