POJ 1722 SUBTRACT(DP)

来源:互联网 发布:谷歌seo外链博客 编辑:程序博客网 时间:2024/05/17 06:47

题意:一个序列,每次可以选择一个位置,把这个位置和下个位置替换为这个位置值减去下个位置值,问一个顺序使得能得到最终结果T

思路:发现其实只有第一个位置必须是-号,不然其他位置都可以任意构造,那么问题转化为一个背包问题,从第3个数字开始,每个数字可以加也可以减,然后这样可以得到一个方案,最后根据这个方案,在去构造顺序,构造的方法问,首先从左往右扫,每个+的位置输出,然后剩下的就不断都取第一个数字即可

代码:

#include <cstdio>#include <cstring>const int N = 105;int n, t, a[N], path[N][N * 200], ans[N];bool dp[N][N * 200];int main() {    while (~scanf("%d%d", &n, &t)) {memset(dp, false, sizeof(dp));for (int i = 1; i <= n; i++) {    scanf("%d", &a[i]);    if (i == 1) dp[i][a[i] + 10000] = true;    else if (i == 2) {dp[i][a[1] + 10000 - a[i]] = true;path[i][a[1] + 10000 - a[i]] = 0;    } else {for (int j = 0; j <= 20000; j++) {    if (j >= a[i] && dp[i - 1][j - a[i]]) {dp[i][j] = true;path[i][j] = 1;    }    if (j + a[i] <= 20000 && dp[i - 1][j + a[i]]) {dp[i][j] = true;path[i][j] = 0;    }}    }}int u = 10000 + t;for (int i = n; i > 1; i--) {    ans[i - 1] = path[i][u];    if (ans[i - 1] == 1) u -= a[i];    else u += a[i];}int tot = 0;for (int i = 1; i <= n - 1; i++) {    if (ans[i] == 1) printf("%d\n", tot + 1);    else tot++;}for (int i = 1; i <= tot; i++)    printf("%d\n", 1);    }    return 0;}


0 0
原创粉丝点击