Groups
题意:一群人三三两两的在路上走着,这是你喊了声“i号报数”,第i个人就立即回答:“前方a人,后方b人”;你挨个人询问后,发现对不上数,其中必有说谎的,问最多有几个说真话的?
思路:令dp[i]表示前i个人中最多说真话的人,那么,他后边一定是n-i人,前边是0~i-1人,用sum[a][b]表示回答前方a人,后方b人的人的数量,a+b一定小于n,sum[a][b]一定小于等于n-a-b;所以状态转移方程就出来了:
dp[i]=max(dp[j]+sum[j][n-i] | 0<=j<=i-1)
#include <bits/stdc++.h>
using namespace std;
int dp[510], sum[510][510];
int main(){
int N;
while(~scanf("%d", &N)){
memset(sum, 0, sizeof(sum));
for(int i=0; i<N; i++){
int a, b;
scanf("%d%d", &a, &b);
if(a+b<N&&sum[a][b]<N-a-b) sum[a][b]++;
}
memset(dp, 0 ,sizeof(dp));
for(int i=1; i<=N; i++){
for(int j=0; j<i; j++){
dp[i]=max(dp[i], dp[j]+sum[j][N-i]);
}
}
printf("%d\n", dp[N]);
}
return 0;
}
本文解析了HDU-4293题目的解题思路及实现方法,采用动态规划求解群体报数问题,通过状态转移方程找出最多说真话的人数。
&spm=1001.2101.3001.5002&articleId=81351713&d=1&t=3&u=bb0405fdf3ee455db9930fc8aa365df6)
467

被折叠的 条评论
为什么被折叠?



