这一星期做了点背包,主要还是学了下数论gcd,lcm,拓展欧几里得,逆元(没大做题目,只是看了遍,也没有明白书上的例题是怎样利用逆元的),素数和素数筛选的方法,做的题还是不够多,只是对素数筛有点印象,还看了点组合数学,刚开了个头
排序就按钩数从大到小排,之后就是01背包了,把挂钩数作为容量,并且如果容量小于a[i]的话,就强行认为是1,转移方程为
dp[i][j]=max(dp[i-1][j],dp[i-1][max(j-g[i].a,0)+1]+g[i].b);
P4138 [JOISC2014] 挂饰 题解_cqbzcky的博客-CSDN博客
#include
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
int n;
struct gua{
int a,b;
}g[2005];
bool cmp(gua c,gua d){
return c.a>d.a;
}
ll dp[2005][2005],sum=0;
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&g[i].a,&g[i].b),sum+=g[i].a;
sort(g+1,g+1+n,cmp);
ll ans=0;
memset(dp,-inf,sizeof(dp));
dp[0][1]=0;
for(int i=1;i<=n;i++)
for(int j=sum;j>=0;j--)
dp[i][j]=max(dp[i-1][j],dp[i-1][max(j-g[i].a,0)+1]+g[i].b),ans=max(ans,dp[i][j]);
cout<
按照题目要求的直接来,直接暴力不会超时;还有一种方法是求一遍背包,然后再逆推减去该消失的物品得到答案
洛谷 P4141 消失之物_Red_Sky_ta的博客-CSDN博客
#include
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,v[2005],f[2005];
void bag(){
memset(f,0,sizeof(f));
f[0]=1;
for(int i=1;i=v[i];j--)
f[j]+=f[j-v[i]],f[j]%=10;
}
}
void print(){
for(int i=1;i<=m;i++) cout<
这道题并不是很难,自己却没有想出来,只是在01背包后面加了个判断而已,以后做题还是要多动脑,不然做再多的题也,没用
洛谷P4394 [BOI2008]Elect 选举 题解_ShineEternal的笔记小屋-CSDN博客
#include
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
int n,v[310],sum=0,f[100000];
bool cmp(int a,int b){
return a>b;
}
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&v[i]),sum+=v[i];
int ans=0;
sort(v+1,v+n+1,cmp);
for(int i=1;i<=n;i++){
for(int j=sum;j>v[i];j--){
f[j]=max(f[j],f[j-v[i]]+v[i]);
if(f[j]-v[i]<=sum/2&&f[j]>sum/2){
ans=max(ans,f[j]);
}
}
}
cout<
这道题看了很久才勉强看明白最后的输出,dp[i]代表走i个人后人墙的高度,如果dp[i]>=0说明他参与了转移,说明走i个人是可能的,dp[i]的值的作用也是为了这个
https://lc--fairycastle.blog.luogu.org/solution-p4823
#include
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
int n,h;
struct ab{
int a,b;
}c[2005];
bool cmp(ab c,ab d){
return c.a+c.b=1;j--){
if(dp[j-1]+c[i].b>=h)
dp[j]=max(dp[j],dp[j-1]-c[i].a);
}
for(int i=n;i>=0;i--){
if(dp[i]>=0){//dp[i]>0说明他被转移过,说明能走i个人
cout<
统计gcd(a,b)的个数,已知gcd(i1,i2,i3),那么gcd(i1,i2,i3,i4)就是gcd(gcd(i1,i2,i3),i4),用sum[i]来表示gcd的个数,则sum[gcd(i1,i2,i3,i4)]=sum[gcd(i1,i2,i3,i4)]+sum[gcd(i1,i2,i3)],最后把所有gcd相加即可
hdu 5656 递推_HARD_UNDERSTAND-CSDN博客
#include
#include
#include
#include
#include
#include
#include
题目最后变为进行n-2轮求gcd看看是否有新的gcd出现,进行完从小到大遍历
#include
#include
#include
#include
#include
#include
#include
看了一个小时也没看出自己到底有啥错误,无奈只能换了种题解的思路,不过题解的思路确实清晰,代码也很简洁
#include
#include
#include
#include
#include
#include
#include
True Story |
一个人如果开始行动说明它必定能到达机场,找到最大的时间间隔,看看有多少人能开始行动即可
(5条消息) The 2021 Sichuan Provincial 四川省赛M.True Story(模拟)_jziwjxjd的博客-CSDN博客
#include
#include
#include
#include
#include
#include
#include
n最大是10^18,普通的打表一定会爆,但是可以想一下我们是要判断n是否满足n=p1^2*p2,假设最小素数是p1,那么p1绝不会超过10^6,因为如果超了,那么n就超范围了;然后对1e6的素数打表,然后进行判断,如果n整除了p1,他要是还能再整除一次p1,说明它不是无平方数,return false;如果循环下来n==1,说明他是无平方数 ,如果大于1,说明n有一个素因子是大于1e6的,这样的素因子不可能超过2个,不然就超范围了,所以看看n是不是平方数就行
Squarefree number HDU - 3826(数论)_Coldfresh的博客-CSDN博客
#include
#include
#include
#include
#include
#include
#include
HDU 6069 数论 区间素数筛 + 赛后反思_新熊君的博客-CSDN博客
#include
#include
#include
#include
#include
#include
#include
神奇天平 |
这道题很简单啊,每次分成m+1堆,让n除以m向上取整就行,当时一直在想和平方的联系,思路在平方的道路上一去不返。。。
#include
using namespace std;
int t,n,m;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
int ans=0;
while(n>1){
n=ceil(n*1.0/(m+1));
ans++;
}
printf("%d\n",ans);
}
return 0;
}
魔法学院(easy version)
这道题也是很简单的,当时也没有想出来,在输入m个魔法时就对s串进行调整(这样做不会超时),最后输出s串ASCII码的和就行
#include
using namespace std;
int n,m;
struct ma{
int r,l,v;
}a[100005];
bool cmp(ma a,ma b){
return a.v>b.v;
}
char s[100005],c;
int main(){
scanf("%d%d",&n,&m);
scanf("%s",s+1);
for(int i=1;i<=m;i++){
scanf("%d%d %c",&a[i].l,&a[i].r,&c);
for(int j=a[i].l;j<=a[i].r;j++)
s[j]=max(s[j],c);
}
int ans=0;
for(int i=1;i<=n;i++) ans+=s[i];
printf("%d\n",ans);
return 0;
}
纯暴力的话必定超时,但想一想情况一共就是有七种: "aa","aba","aca","abca","acba","abbacca","accabba",只要用字符串的find方法找出s串是否含有这七种子串即可,从小的开始搜索以保证字符串长度最小
#include
using namespace std;
int t,n;
string s,a[7]={"aa","aba","aca","abca","acba","abbacca","accabba"};
int main(){
//freopen("in.txt","r",stdin);
scanf("%d",&t);
while(t--){
scanf("%d",&n);
cin>>s;
int res=-1;
for(int i=0;i<7;i++){
if(s.find(a[i])!=-1){
res=a[i].size();
break;
}
}
cout<
区间素数筛的问题,这个可以当做是一个模板了;
poj 2689 Prime Distance 区间素数筛+大数 模板_人生如戏-CSDN博客
#include
#include
#include
#include
#include
#include
#include