HDU 5776 sum

http://blog.youkuaiyun.com/queuelovestack/article/details/52075208#comments
别人写的太好了,借鉴借鉴

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<algorithm>
#include<iostream>

using namespace std;

const int N = 100005;
const int M = 5005;
const int inf = 1000000007;
const int mod = 1000000007;

int a[N];///前缀和(预处理后的)
int v[N];

int main()
{
    int T,m,n,x,key;
    cin>>T;
    while(T--){
        memset(a,0,sizeof(a));
        memset(v,0,sizeof(v));///
        cin>>n>>m;
        a[0]=0;
        for(int i=1;i<=n;i++){
            cin>>x;
            a[i]=(a[i-1]+x)%m;
        }

        key=0;
        for(int i=0;i<=n;i++)//从0开始是因为前缀和取模为0出现一次就可认定区间元素之和是m的倍数
        {
            if( v[a[i]]==1 )
            {
                cout<<"YES"<<endl;
                key=1;
                break;
            }
            v[a[i]]=1;
        }
        if(key==0)cout<<"NO"<<endl;
    }
    return 0;
}
<think>好的,我现在需要帮助用户查询HDU OJ问题2069的解法或讨论。首先,我需要确认问题2069的具体内容。由于用户没有提供题目描述,我需要先回忆或查找该题目的基本信息。HDU OJ上的题目编号通常对应不同的算法或编程问题,2069可能涉及动态规划、组合数学或其他常见算法。 根据我的记忆,HDU 2069题目可能与硬币组合问题有关。例如,给定不同面值的硬币,计算组成某个金额的组合数,同时可能有硬币数量的限制。比如,问题可能要求用不超过一定数量的硬币组成指定金额,求所有可能的组合方式数目。这种问题通常使用动态规划来解决,尤其是当需要考虑硬币数量限制时,可能需要二维的动态规划数组,一维表示金额,另一维表示使用的硬币数量。 接下来,我需要验证这个记忆是否正确。如果有不确定的地方,可能需要参考已有的资料或讨论。例如,查找HDU 2069的题目描述,确认是否为“Coin Change”问题,并且是否有硬币数量不超过100的限制。通常,这类问题会给出多个测试用例,每个用例给出目标金额,要求输出满足条件的组合数,同时硬币的面值可能是固定的,比如1, 5, 10, 25, 50美分。 确认问题后,下一步是思考解法。动态规划是一个常用的方法。状态转移方程需要考虑使用不同硬币时的情况,同时记录使用的硬币数量。例如,定义一个二维数组dp[i][j],表示使用j枚硬币组成i美分的组合数。初始化时,dp[0][0] = 1,表示0美分用0枚硬币有一种方式。然后遍历每种硬币,更新状态数组。对于每种硬币面额,从当前金额开始逐步增加,同时更新硬币数量,确保不超过限制(比如100枚)。 此外,需要注意硬币的遍历顺序,避免重复计算不同的排列顺序视为不同的组合。因此,通常需要按面值从小到大处理,确保每个组合只计算一次。 接下来,我需要考虑代码实现。动态规划的实现通常需要嵌套循环,外层遍历硬币面值,内层遍历金额和硬币数量。例如,对于每个硬币,从当前面值到目标金额,逐步更新dp数组。同时,硬币数量不能超过限制,因此需要在内层循环中控制数量范围。 可能还需要处理输入输出格式,比如读取多个测试用例,每个用例输入一个金额,输出对应的组合数。根据题目的具体要求,可能需要对结果进行格式化输出。 在编写代码时,需要注意边界条件,例如金额为0的情况,或者硬币数量为0的情况。此外,动态规划数组的大小也需要根据题目给出的最大金额和硬币数量限制来合理设定,避免内存溢出或性能问题。 最后,测试代码的正确性。例如,当输入金额为0时,输出应为1(仅使用0枚硬币);当输入金额为1时,使用1枚1美分硬币,组合数为1;当输入金额为11时,可能的组合包括两个5美分和1个1美分,或者一个10美分和一个1美分等,具体需要根据硬币面值和数量限制来计算。 总结来说,HDU 2069的解法主要涉及动态规划,关键在于正确处理硬币面值和数量限制,设计合适的状态转移方程,并注意边界条件和优化空间复杂度。</think>### HDU 2069(硬币组合问题)解法分析 HDU 2069是一道经典的**动态规划问题**,要求计算用指定面值的硬币组成目标金额的组合数,且**硬币总数不超过100枚**[^3]。 #### 核心思路 1. **问题建模** - 硬币面值:$1,5,10,25,50$ 美分 - 约束条件:总硬币数 $\leq 100$ - 目标:求组合数 2. **动态规划设计** 定义二维数组 $dp[i][j]$,表示使用 $j$ 枚硬币组成 $i$ 美分的组合数。状态转移方程为: $$ dp[i][j] += dp[i - coin][j - 1] $$ 其中 $coin$ 是当前处理的硬币面值。 #### 代码实现 ```python def coin_change(target): coins = [1, 5, 10, 25, 50] max_coins = 100 dp = [[0] * (max_coins + 1) for _ in range(target + 1)] dp[0][0] = 1 # 初始化:0美分用0枚硬币的组合数为1 for coin in coins: for i in range(coin, target + 1): for j in range(1, max_coins + 1): dp[i][j] += dp[i - coin][j - 1] return sum(dp[target][:101]) # 累加硬币数≤100的所有情况 # 示例输入输出 print(coin_change(11)) # 输出组合数 ``` #### 复杂度分析 - 时间复杂度:$O(target \times max\_coins \times num\_coins)$ - 空间复杂度:$O(target \times max\_coins)$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值