Sicily 1828 Minimal(动态规划)
2010-09-29 01:14
435 查看
//动态规划 //这题的关键在于先排序,只有先排序,后面动规的思路才能出来,我就是想不到得先排序,卡了好久还得别人提醒 //我是NC不解释 //题意是对2个集合寻找N对数对,使得数对的距离之和最小 //如果你先排好序,那么用DP(i,j)表示A集合的前i个点与B集合前j个点的最优值 //那么对于第i+1个A集合的点而言,他的最优解就是前i个点与B集合前j个点的最优值加上第i+1个点与第j+1个点的距离 //或许i+1与j+1配对不是最好的,它可能比上一个状态DP(i+1,j)要差 //综上 //动态转移方程就是 //dp(i,j) = min(dp(i-1,j-1) + dis(i,j),dp(i,j-1)); //当然这题的边界处理也比较重要 //最初的状态自然是对排序后的点按集合下表按顺序配对 //1-1,2-2,3-3......n-n,X-n+1...X-m;详细的处理可见代码 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; int A[505],B[505],N,M; int dp[505][505],dis[505][505]; int main() { //freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&N,&M); memset(dp,0,sizeof(dp)); for(int i = 1;i <= N;++i) scanf("%d",&A[i]); for(int j = 1;j <= M;++j) scanf("%d",&B[j]); sort(A+1,A+N+1); sort(B+1,B+M+1); for(int i = 1;i <= N;++i) for(int j = 1;j <= M;++j) dis[i][j] = abs(A[i] - B[j]); for(int i = 1;i <= N;++i) { if(i == 1) dp[i][i] = dis[1][1]; else dp[i][i] = dp[i-1][i-1] + dis[i][i];//初始化边界 } for(int i = 1;i <= N;++i) for(int j = i+1;j <= M;++j) dp[i][j] = min(dp[i-1][j-1] + dis[i][j],dp[i][j-1]);//状态转移 printf("%d/n",dp [M]); } return 0; }
相关文章推荐
- sicily 1264(动态规划)
- Sicily1767(双线程动态规划)
- Sicily1828
- Sicily 1264. Atomic Car Race 解题报告(动态规划)
- sicily 1176 two ends 动态规划解题
- Sicily1011动态规划
- sicily 1011. Lenny's Lucky Lotto 动态规划
- sicily 1176. Two Ends (Top-down 动态规划+记忆化搜索 v.s. Bottom-up 动态规划)
- Sicily 1327 Pinary (SOJ 1327) 【dp 动态规划】
- Sicily 1001.Alphacode | 动态规划
- Sicily 1011——动态规划
- sicily 1264. Atomic Car Race 动态规划
- Sicily 1346 金明的预算方案 (SOJ 1346) 【DP 动态规划-背包问题】
- sicily 1415. Honeycomb Walk【动态规划】
- sicily 13602(动态规划)
- 【动态规划】Sicily1280 Permutation
- [Sicily Coins] 动态规划 多重背包问题
- Sicily 1091 Maximum Sum(动态规划)
- sicily 1176 (动态规划)
- sicily 1419(动态规划)