hdu4960(dp)

来源:互联网 发布:一诺网络 编辑:程序博客网 时间:2024/05/16 17:41

肯死爹的一题,再次犯了奇葩的错误,连跪20把。。。。。。。

题意:

给出一个数字串,给出数字串合并个数对应花费,问如何合并形成回文串并且花费最烧。

解法:

算出回文的合并,然后对两端dp,枚举所有情况找到最优解。

#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>using namespace std;#define oo 0x3f3f3f3f#define maxn 5010int dp[maxn];int v[maxn], a[maxn];int L[maxn], R[maxn];int rnum, lnum, len, rsum, lsum;int n, ans;int main(){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", &v[i]);len = 0;for (int i = 1, j = n; i < j; i++, j--){lsum = a[i];rsum = a[j];lnum = rnum = 1;while (lsum != rsum){if (i >= j)break;if (lsum < rsum){lsum += a[++i];lnum++;}else{rsum += a[--j];rnum++;}}if (lsum == rsum){len++;L[len] = lnum;R[len] = rnum;}}for (int i = 1; i <= len; i++){int l1 = 0, l2 = 0;dp[i] = oo;for (int j = i; j >= 1; j--){l1 += L[j];l2 += R[j];dp[i] = min(dp[i], dp[j - 1] + v[l1] + v[l2]);}}ans = v[n];for (int i = 1; i <= len; i++){n -= L[i] + R[i];ans = min(ans, dp[i] + v[n]);}printf("%d\n", ans);}return 0;}

0 0
原创粉丝点击