题意:某人竞选,花钱 拉票,每个社区都有相应的信息,按照公式求出得票数(四舍五入)结果一样的时候(按 第一个社区的花费最多为准,依次类推)
思路:竟然要求结果一样的时候,按靠前的社区的花费多的为准,那么显然我们要从前往前推,按照背包的思想递推,dp[i][j]表示从第i个社区到n-1个社区花费j-k的最大得票数
还有的地方就是要标记在第i个的花费
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 110; struct node{ int N,Ip,R; }arr[MAXN]; int dp[MAXN][MAXN],f[MAXN][MAXN]; int n,m; int main(){ int t = 1; while (scanf("%d%d",&m,&n) && n+m){ memset(dp,0,sizeof(dp)); memset(f,0,sizeof(f)); printf("Case %d: ",t++); for (int i = 0; i < n; i++) scanf("%d%d%d",&arr[i].N,&arr[i].Ip,&arr[i].R); for (int i = 0; i <= 100; i++){ dp[n-1][i] = (arr[n-1].Ip+i/(i+10.1)*arr[n-1].R)/100*arr[n-1].N+0.5; f[n-1][i] = i; } for (int i = n-2; i >= 0; i--) for (int j = 0; j <= 100; j++){ int Max = 0,Maxk; for (int k = 0; k <= j; k++){ int temp = (int)(dp[i+1][j-k]+(arr[i].Ip+k/(k+10.1)*arr[i].R)/100*arr[i].N+0.5); if (temp >= Max){ Max = temp; Maxk = k; } dp[i][j] = Max; f[i][j] = Maxk; } } printf("%d\n",dp[0][m]); int temp = m,flag = 1; for (int i = 0; i < n; i++){ if (flag){ printf("%d:%d",i,f[i][temp]); flag = 0; } else printf(" %d:%d",i,f[i][temp]); temp -= f[i][temp]; } printf("\n"); } return 0; }
UVALive - 4905 Pro-Test Voting
原文:http://blog.csdn.net/u011345136/article/details/18674543