加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ PKU 1745 动态规划

(2010-03-31 20:32:00)
标签:

poj

pku

1745

分类: 动态规划

    题目描述:给你n个整数,和一个k值(2<=k<=100),问在这n个数之间的n-1的位置任意放加减号,问有没有一种情况使结果整除k。

    dp即可。dp[i][j] = 1表示在第i个数字时,有一种组合可以使结果模k为j。

    易知, -(k - 1) <= j <= k - 1

    状态转移:

    设x[i]为第i个数字。

    dp[i][j] = dp[i - 1][(j - x[i]) % k] || dp[i - 1][(j x[i]) % k];

    注意第一个数字要特判一下,因为第一个数字前没有加减号,或者说:只有加号。

    最后只要看dp[n][0]是否等于1,即:到第n个数的时候,有没有组合的结果模k等于0,即整除k。

#include<iostream>
using namespace std;
bool dp[10000][200];
int main()
{
    int n, k, x, mid = 100, temp;
    scanf("%d%d", &n, &k);
    memset(dp, 0, sizeof(dp));
    for(int i = 0; i < n; i )
    {
        scanf("%d", &x);
        if (i == 0)
            dp[i][mid x % k] = 1;
        else
            for(int j = mid - k 1; j <= mid k - 1; j )
            {
                if (dp[i - 1][j])
                {
                    temp = (j x - mid) % k;
                    dp[i][temp mid] = 1;
                    temp = (j - x - mid) % k;
                    dp[i][temp mid] = 1;
                }
            }
    }
    if (dp[n - 1][mid])
        printf("Divisible\n");
    else
        printf("Not divisible\n");
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有