C - Thief in a Shop - dp完全背包-FFT生成函数
思路 :严格的控制好k的这个数量,这就是个裸完全背包问题.(复杂度最极端会到1e9)
他们随意原来随意组合的方案,与他们都减去 最小的 一个 a[ i ] 组合的方案数目是不会改变的
那么我们就 dp [ i ]表示 i 这个价格需要的最少 个数。 这样求最小个数保证不会漏解
然后 如果这个 i 能通过 1 - k 个物品组合出来,那么 一定能通过k 个物品组合出 i + k * a [ 1 ].
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define maxn 1234567
int n,k,dp[maxn],a[maxn];
int v[maxn],mi,sum,id,base;
map<int,bool>vis;
vector<int>ans;
int main()
{
scanf("%d%d",&n,&k);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
if(vis[a[i]]==0)
{
vis[a[i]]=1;
v[++id]=a[i];
}
}
sort(v+1,v+1+id);
base=v[1]*k;
for(int i=2; i<=id; i++)
v[i]-=v[1];
sum=v[id]*k;
memset(dp,inf,sizeof(dp));
dp[0]=0;
for(int i=2; i<=id; i++)
for(int j=v[i]; j<=sum; j++)
dp[j]=min(dp[j],dp[j-v[i]]+1);
for(int i=0; i<=sum; i++)
{
if(dp[i]>k)continue;
ans.push_back(i+base);
}
int len=ans.size();
for(int i=0; i<len; i++)
{
printf("%d",ans[i]);
if(i<len-1)printf(" ");
else printf("\n");
}
return 0;
}
思路:最初有的ai 初始化系数为1进行操作k次卷积。注意补零操作,然后注意最大长度,
也就是最终结果可能得到的最大指数 ....
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <cstring>
#include <cmath>
using namespace std;
const double PI = acos(-1.0);
struct complex
{
double r,i;
complex(double _r = 0.0,double _i = 0.0)
{
r = _r;
i = _i;
}
complex operator +(const complex &b)
{
return complex(r+b.r,i+b.i);
}
complex operator -(const complex &b)
{
return complex(r-b.r,i-b.i);
}
complex operator *(const complex &b)
{
return complex(r*b.r-i*b.i,r*b.i+i*b.r);
}
};
void change(complex y[],int len)
{
int i,j,k;
for(i = 1, j = len/2; i < len-1; i++)
{
if(i < j)swap(y[i],y[j]);
k = len/2;
while( j >= k)
{
j -= k;
k /= 2;
}
if(j < k) j += k;
}
}
void fft(complex y[],int len,int on)
{
change(y,len);
for(int h = 2; h <= len; h <<= 1)
{
complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
for(int j = 0; j < len; j+=h)
{
complex w(1,0);
for(int k = j; k < j+h/2; k++)
{
complex u = y[k];
complex t = w*y[k+h/2];
y[k] = u+t;
y[k+h/2] = u-t;
w = w*wn;
}
}
}
if(on == -1)
for(int i = 0; i < len; i++)
y[i].r /= len;
}
const int MAXN = 5234567;
complex x1[MAXN],x2[MAXN];
char str1[MAXN/2],str2[MAXN/2];
int sum[MAXN];
int siz[1100];
int main()
{
int n,k;
scanf("%d %d", &n, &k);
int x;
int MAX = 0;
memset(siz,0,sizeof(siz));
for(int i = 1; i <= n; i++)
{
scanf("%d", &x);
siz[x] = 1;
MAX = max(MAX,x);
}
int len1 = MAX * k;
int len = 1;
while(len < len1) len <<= 1;
for(int i = 0; i < len; i++)
x1[i] = complex(siz[i],0);
x2[0] = complex(1,0);
for(int i=1; i < len; i++)
x2[i] = complex(0,0);
fft(x1,len,1);
fft(x2,len,1);
while(k)
{
if(k % 2 == 1)
{
for(int i = 0; i <len; i++)
x2[i] = x1[i]*x2[i];
fft(x2,len,-1);
for(int i = 0; i < len; i++)
{
sum[i] = (int)(x2[i].r + 0.5);
if(sum[i])x2[i]=complex(1,0);
else x2[i]=complex(0,0);
}
fft(x2,len,1);
}
for(int i =0; i < len; i++)
x1[i] = x1[i]*x1[i];
fft(x1,len,-1);
for(int i = 0; i < len; i++)
{
sum[i] = (int)(x1[i].r + 0.5);
if(sum[i])x1[i]=complex(1,0);
else x1[i]=complex(0,0);
}
fft(x1,len,1);
k /= 2;
}
fft(x2,len,-1);
for(int i = 0; i < len; i++)
{
sum[i] = (int)(x2[i].r + 0.5);
}
for(int i = 0; i <len; i++)
{
if(sum[i])
printf("%d ",i);
}
return 0;
}
C - Thief in a Shop - dp完全背包-FFT生成函数的更多相关文章
- Educational Codeforces Round 9 E. Thief in a Shop dp fft
E. Thief in a Shop 题目连接: http://www.codeforces.com/contest/632/problem/E Description A thief made hi ...
- codeforces632E. Thief in a Shop (dp)
A thief made his way to a shop. As usual he has his lucky knapsack with him. The knapsack can contai ...
- CF632E Thief in a Shop 和 CF958F3 Lightsabers (hard)
Thief in a Shop n个物品每个价值ai,要求选k个,可以重复.问能取到哪几个价值? 1 ≤ n, k ≤ 1000,1 ≤ ai ≤ 1000 题解 将选一个物品能取到的价值的01生成函 ...
- codeforces 632+ E. Thief in a Shop
E. Thief in a Shop time limit per test 5 seconds memory limit per test 512 megabytes input standard ...
- codeforces Educational Codeforces Round 9 E - Thief in a Shop
E - Thief in a Shop 题目大意:给你n ( n <= 1000)个物品每个物品的价值为ai (ai <= 1000),你只能恰好取k个物品,问你能组成哪些价值. 思路:我 ...
- codeforces 632E. Thief in a Shop fft
题目链接 E. Thief in a Shop time limit per test 5 seconds memory limit per test 512 megabytes input stan ...
- USACO Money Systems Dp 01背包
一道经典的Dp..01背包 定义dp[i] 为需要构造的数字为i 的所有方法数 一开始的时候是这么想的 for(i = 1; i <= N; ++i){ for(j = 1; j <= V ...
- 树形DP和状压DP和背包DP
树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...
- HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)
HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...
随机推荐
- jQuery 条件搜索查询 实时取值 升降序排序
一.鼠标点击获取搜索条件中的被选中的值 创建方法 getAttrValue() 方法,每次的 .click 都要调用 function getAttrValue(){} 例如,把选中的值给到属性 ...
- 五十八、linux 编程——UDP 编程 广播
58.1 广播介绍 58.1.1 介绍 广播实现一对多的通讯 它通过向广播地址发送数据报文实现的 58.1.2 套接字选项 套接字选项用于修饰套接字以及其底层通讯协议的各种行为.函数 setsocko ...
- 读取FTP上的某个文本文档内容到本地
/// <summary> /// 读取FTP服务器文本内容 /// </summary> /// <param name="strPath"> ...
- JavaScript之Map对象
前言 工欲善其事,必先利其器.这是一款以前在前端项目中没有使用过的.有趣的对象,咱来看看如何使用~ 并非arrayObj.map(function) //arrayObj.map与arrayObj.f ...
- 一些C++的语法
一.类的析构函数 类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行. 析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何 ...
- maven配置及IDEA配置maven环境
一. maven的下载及配置 1. maven下载地址 可以在网址:https://maven.apache.org/download.cgi下载最新版本的maven 2. maven文件解压缩 解压 ...
- ps切图技巧
步骤1: ps打开psd文件 步骤2: 点击移动工具,观察左上角的自动选择是否有勾选 ,如果没有最好勾选,对应的选项有图层和组,善于切换这个功能能够有效快速的找到你要的区域 步骤3: 找到要切图的元素 ...
- json基础小结
定义:json是一种前后端数据传送的格式规定json对象,json字符串 (区别 json字符串是有json格式的字符串)1.创建(两中json结构,一种是对象,一种是数组)json对象:var ao ...
- Apple Tree POJ - 2486 (树形dp)
题目链接: D - 树形dp POJ - 2486 题目大意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值 学习网址:https://blog.c ...
- mvc路由报错
1.添加新项目时,把就项目的dll一起拷贝过来.生成项目,编译通过,打开页面时报错:“找到多个与名为“Home”的控制器匹配的类型 ”,网上的解决方案是,加命名空间,解决,但是自己这边删掉bin中原来 ...