TYVJ1096

也不知道属于什么DP,反正就是DP算了。。
设dp[i][j]表示前i个数组合成j的最多方案数和恰好装满的01背包类似
一开始的思路是dp[i][j]=dp[i-1][j-a[i]]+1;真不知道当时是怎么能想出这个方程来的,或许是看到长得不错就要它了吧。。
后来敲代码,怎么调都对不了,后来就反思,老觉得少点东西,
原来它在这里:对于dp[i][j]来说,有两种从i-1的转移过来的方式 :
一种是组合中没有a[i]的,即由前i-1个数组成j,dp[i-1][j] 另一种是组合中包含a[i]的(虽说包含,但是这种组合的方案数可能为0),即由前i-1个数组成j-a[i]的方案数转移过来

状态方程:
|dp[i-1][j] j<a[i]
dp[i][j] = |
|dp[i-1][j]+dp[i-1][j-a[i]] j>=a[i]

边界条件:(根据个人的思考方式来理解来找边界)因为是根据i一层一层的向上推所以i最小的时候的那一层需要求出,这也很简单i=1时只有dp[1][a[1]]=1;别的都是0 另外会出现dp[i-1][j-a[i]],这里的j-a[i]可能为0所以需要把竖着的边界也求出,这个也很好求,不管前几个数都不可能组合出0,所以dp[i][0] = 1;(i>=1)

今天五题的最后一个了,终于完了,该睡了。。。。啊喔啊喔~~

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 10005;
 7 int a[105],dp[101][maxn];
 8 int main()
 9 {
10     int n,m;
11     while(cin>>n>>m)
12     {
13         for(int i = 1;i<=n;++i)scanf("%d",a+i);
14         //sort(a+1,a+1+n);
15         memset(dp,0,sizeof(dp));
16         dp[1][a[1]] = 1;
17         for(int i = 1;i<=n;++i)dp[i][0] = 1;
18         for(int i = 2;i<=n;++i)
19             for(int j = 1;j<=m;++j)
20                 if(j>=a[i])dp[i][j] = dp[i-1][j]+dp[i-1][j-a[i]];
21                 else dp[i][j] = dp[i-1][j];
22 //        for(int i = 1;i<=n;++i)
23 //        {
24 //            for(int j = 1;j<=n;++j)
25 //                printf("%d ",dp[i][j]);
26 //            printf("\n");
27 //        }
28         printf("%d\n",dp[n][m]);
29     }
30     return 0;
31 }
时间: 2024-10-10 18:26:59

TYVJ1096的相关文章

tyvj1096 数字组合

描述 在N个数中找出其和为M的若干个数.先读入正整数N(1<N<100)和M(1<M<10000), 再读入N个正数(可以有相同的数字,每个数字均在1000以内), 在这N个数中找出若干个数, 使它们的和是M, 把满足条件的数字组合都找出来以统计组合的个数,输出组合的个数(不考虑组合是否相同).要求你的程序运行时间不超过1秒. 输入格式 第一行是两个数字,表示N和M.第二行起是N个数. 输出格式 就一个数字,表示和为M的组合的个数. 测试样例1 输入 4 4 1 1 2 2 输出

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

TYVJ1172 自然数拆分Lunatic版 - 背包DP[完全背包]

TYVJ1172 自然数拆分Lunatic版 传送门 思路: 类比TYVJ1096 数字组合 , 本题的数字可以重复使用,所以是一个完全背包模型.\(f[i,j]\)表示当前选到第\(i\)类数字凑成的数字为\(j\)的方案数. Tips: 1.模数为\(2^64\),需要用\(unsigned~long~long\)存储,所以\(f\)数组也要用\(unsigned~long~long\)存储. 2.因为是自然数拆分,所以最终答案减去凑成0的方案数. AC Code: #include<cst