蓝桥杯---波动数列(dp)(背包)(待解决)
1 3 0 2 -1 1 -2 ...
这个数列中后一项总是比前一项增加2或者减少3。
栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?
对于30%的数据,1<=n<=30,0<=s<=30,1<=a,b<=30;
对于50%的数据,1<=n<=50,0<=s<=50,1<=a,b<=50;
对于70%的数据,1<=n<=100,0<=s<=500,1<=a, b<=50;
对于100%的数据,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a, b<=1,000,000。
开始的时候就感觉这道题应该没有那么简单,但是还是抱着试试看的心情做了一下,结果。。。就没有结果了,果断20%,剩下的全是TL,即使是之后的剪枝也是没什么作用(其实这也正常,粗略的算一下也会知道会超时的)
#include <iostream>
#include <cstdio>
using namespace std;
int count=0,n,result,a,b,sum=0;
bool sub(int i,int ceng){
int ss=(2*i+(ceng-1)*-b)*ceng/2;
return sum+ss<=result;
}
bool add(int i,int ceng){
int ss=(2*i+(ceng-1)*a)*ceng/2;
return sum+ss>=result ;
}
void dfs(int i,int cou){ sum+=i;
int temp=count; if(sum==result&&cou==n) { count++; } //cout<<i<<' ';
if(cou>=n){ sum-=i; return ;} if(sub(i-b,n-cou))//如果剩下的全部为减法都不能成立的话就直接不用继续深搜下去了
//但是这样的优化好像是杯水车薪,依然超时
dfs(i+a,cou+1);
//if(count!=temp) cout<<i<<' ';
// temp=count;
if(add(i+a,n-cou))//与上同理
dfs(i-b,cou+1);
//if(count!=temp) cout<<i<<' ';
sum-=i;
return;
}
int main(){
scanf("%d%d%d%d",&n,&result,&a,&b);
int top=(result*2/n-(n-1)*-b)/2, bott=(result*2/n-(n-1)*a)/2;
cout<<top<<' '<<bott<<endl;
for(int i=bott; i<=top; i++){
// cout<<"底数为"<<i<<" "<<sum<<endl;
dfs(i,1);
// cout<<endl;
}
cout<<count<<aaa<<endl;
return 0;
}
最后才知道是动态的一道题,不过好像还是有点不太懂,之后整理吧。。。
找到了下面的一个代码:(找了好长时间才找到这么一个100%AC的,但是好像还是有点不太懂)
http://blog.csdn.net/quzhongrensan511/article/details/23156363
原题可化为nx+(n-1)p(1)+(n-2)p(2)+…+p(n)=s,其中n为数列长度,x为初值,p(i)={a,-b}。本题的目标是给出不同的p序列,使得等式成立并且x为整数。自然而然可以想到枚举的方法,给出不同的序列,令t=s-Σi*p(n-i),若t%n==0则是一种可取的方案。直接枚举肯定会超时,所以需要进一步考虑。注意到,a和b的总数为n(n-1)/2个(所有p前系数的和),所以我们只需要枚举a的个数,将t修改为t=s-ca-(n(n-1)/2-c)b,c为枚举数,0<=c<=n(n-1)/2。
当然满足条件的c的个数并不是我们想要的,因为给定一个c,存在多种组合方式。但是可以发现,每个c都是由1~n-1中若干元素组成的。于是问题转化为求容量为c的01背包的方案数。对于本题,可以写为:(f[i][j]为前i个物体构成j体积的方案数,第i个物体的体积为i)
f[i][j]=f[i-1][j], i>j
f[i-1][j]+f[i-1][j-i], j>=i
注意到递推式只和前一状态有关,故可以使用滚动数组;根据定义,可以预先算出每一个f[n][i],避免重复计算;前i个货物最多只能达到i*(i+1)/2的体积,所以大于这个数值的部分没有必要计算。具体的请看代码,其实就这么几行。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define MAXN 1100
#define MOD 100000007
using namespace std; int F[2][MAXN*MAXN];
int e = 0;
long long n,s,a,b;
int cnt = 0; void calc(int elem)
{
int i,j;
memset(F,0,sizeof(F));
F[e][0]=1;
for(i=1;i<n;i++)
{
e=1-e;
for(j=0;j<=i*(i+1)/2;j++)
{
if(i>j)
F[e][j]=F[1-e][j];
else
F[e][j]=(F[1-e][j]+F[1-e][j-i])%MOD;
}
}
} int main()
{
scanf("%I64d%I64d%I64d%I64d",&n,&s,&a,&b);
long long i,t;
calc(n*(n-1)/2);
for(i=0; i<=n*(n-1)/2; i++)
{
t = s - i*a + (n*(n-1)/2-i)*b;
if(t%n==0)
cnt = (cnt+F[e][i])%MOD;
}
printf("%d",cnt);
return 0;
}
蓝桥杯---波动数列(dp)(背包)(待解决)的更多相关文章
- 转 蓝桥杯 历届试题 波动数列 [ dp ]
传送门 历届试题 波动数列 时间限制:1.0s 内存限制:256.0MB 锦囊1 锦囊2 锦囊3 问题描述 观察这个数列: 1 3 0 2 -1 1 -2 ... 这个 ...
- 梳理一下最近准备蓝桥杯时学习DP问题的想法
学习时间不长,记录的只是学习过程的思路和想法,不能保证正确,代码可以在acwing上AC. 01背包问题: 1.首先是简单的01背包问题 2.先确定状态,f[i][j]表示有第i件物品,时间为j的最大 ...
- Java实现 蓝桥杯 算法提高 01背包
算法提高 01背包 时间限制:1.0s 内存限制:256.0MB 问题描述 给定N个物品,每个物品有一个重量W和一个价值V.你有一个能装M重量的背包.问怎么装使得所装价值最大.每个物品只有一个. 输入 ...
- 蓝桥杯 求最大值 dp
这题很暴力的一个DP,d[i][j]表示前i个数对选择一些Ai的和为j的最大Bi和. 状态转移方程: dp[i][j]=max(dp[i][j],dp[i-1][j-sc[i].a]+sc[i].b) ...
- BEGIN-4_蓝桥杯_Fibonacci数列
问题描述 Fibonacci数列的递推公式为:Fn=Fn-+Fn-,其中F1=F2=. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n. 输 ...
- 计蒜客 蓝桥杯模拟 瞬间移动 dp
在一个 n \times mn×m 中的方格中,每个格子上都有一个分数,现在蒜头君从 (1,1)(1,1) 的格子开始往 (n, m)(n,m) 的格子走.要求从 (x_1,y_1)(x1,y1 ...
- 蓝桥杯BASIC-13 数列排序
问题描述 给定一个长度为n的数列,将这个数列按从小到大的顺序排列.1<=n<=200 输入格式 第一行为一个整数n. 第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000. 输 ...
- BASIC-13_蓝桥杯_数列排序
示例代码: #include <stdio.h>#include <stdlib.h> int main(void){ int n = 0 ; int i = 0 , j = ...
- BASIC-4_蓝桥杯_数列特征
示例代码: #include <stdio.h>#include <stdlib.h> int main(void){ int n = 0 ; int i = 0 , max ...
随机推荐
- shiro权限验证标签
实例: spring-shiro.xml /admin/repairType/index = roles["ROLE_ADMIN"] /admin/user=roles[" ...
- js为DIV动态设置id属性
<script> var objs=document.getElementById("iproduct").getElementsByTagName("div ...
- LintCode "Partition Array by Odd and Even"
One pass in-place solution: all swaps. class Solution { public: /** * @param nums: a vector of integ ...
- android打印调用栈
在某些机器上,不能下断点,出现了某个诡异的问题,想到唯一的解决方式,就是打印调用栈了,google发现这个,记录下,以后备用 Log.d(",Log.getStackTraceString( ...
- 从官方下载 Bootstrap 版本 并写 第一个页面
从官方下载 Bootstrap 版本 页面内容参考自 http://www.cnblogs.com/sanjuantianshu/p/3935120.html bootstrap-3.2.0.zip ...
- SQL server 学习笔记1
1.查询安装的排序规则选项喝当前的排序规则服务器属性 select * from fn_helpcollations(); 2.查看当前服务器的排序规则 select serverproperty(' ...
- 单选按钮选中js的处理
function FinancialinfosetController($scope, $http, $timeout, $location, $rootScope, $routeParams) { ...
- OpenCV中Delaunay三角网算法例子
#include <opencv2/opencv.hpp> #include <vector> using namespace cv; using namespace std; ...
- Shell_Oracle Erp和其他系统Interface资料传输通过Shell进行控制(案例)
2014-06-26 Created By BaoXinjian
- Codeforces Round #366 (Div. 2) C Thor(模拟+2种stl)
Thor 题意: 第一行n和q,n表示某手机有n个app,q表示下面有q个操作. 操作类型1:app x增加一条未读信息. 操作类型2:一次把app x的未读信息全部读完. 操作类型3:按照操作类型1 ...