博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
lightoj 1125【背包·从n个选m个】
阅读量:4482 次
发布时间:2019-06-08

本文共 1197 字,大约阅读时间需要 3 分钟。

题意:
给你 n 个背包,然后给你两个数,D,M,问你从n个里面挑M个出来,有多少种方法能够整除D;
思路:
试想我先不挑M个出来的话,仅仅是构造一个D的倍数,其实就是构造一个数的话,
其实就是个递推,然后方案的叠加
挑M个,D的倍数。
能对M个状压;
但是对于D的倍数呢?
其实就是取膜就好了,比如5的倍数,
那么dp[个数][j]+=dp[个数-1][j-X];(个数都是状压了)
但是现在是200个里面挑10个啊。。。
不行的话就再加一维。
所以还是要从前 i 个物品推过来。。。
所以现在可以搞成dp[i][j][k]表示前i个物品选j个%D=k时的方案数;= =

每次逆推可以把第一维去掉,时间复杂度也OK;

总的来说就是:能状压么?不能解决这个事情就再开一维,一维不行上二维,二维不行三维先上了再说;(PS:n个里面选m个真是玄学。。第二遍做。。。还是碰壁GG。

#include 
using namespace std;typedef long long LL;typedef unsigned long long ULL;typedef pair
PII;const double eps=1e-5;const double pi=acos(-1.0);const int INF=0x3f3f3f3f;const int N=1e2+10;int a[N*2];LL dp[12][25];int main(){ int cas=1; int n,w,q,d,m; int t,x,sum; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",&a[i]); printf("Case %d:\n",cas++); for(int k=1;k<=q;k++) { scanf("%d%d",&d,&m); memset(dp,0,sizeof(dp)); dp[0][0]=1LL; for(int i=1;i<=n;i++) { int temp=a[i]%d; for(int j=m;j>=1;j--) for(int x=0;x

转载于:https://www.cnblogs.com/keyboarder-zsq/p/6777490.html

你可能感兴趣的文章
IOS 实现流媒体 播放
查看>>
P3168 [CQOI2015]任务查询系统
查看>>
完备性
查看>>
Common Css [记录]
查看>>
H5新特性-----type=file文件上传
查看>>
快递查询接口
查看>>
OpenCV-Python 学习(二) OPENCV 中核心操作
查看>>
Redis进阶实践之十 Redis哨兵集群模式
查看>>
用myeclipse打jar包,使其包含依赖jar包的指向
查看>>
Linux删除乱码非空目录
查看>>
zbb20180913 java thread ThreadLocal锁示例代码
查看>>
jquery --cookie
查看>>
Java和Android学习
查看>>
将DataTable中的数据导出成Excel
查看>>
线性回归
查看>>
NOI 2019 网络同步赛 游记
查看>>
[网络基础 ] 分层体系结构
查看>>
JavaScript焦点事件、鼠标事件和滚轮事件使用详解
查看>>
Qt 5 常见错误汇总
查看>>
2018.6.27 Ajax实现异步刷新
查看>>