这次我特别的稳~~
1,2,4三道没有思维难度的水题都拿到了满分;
再骗个20,就拿到了这次的第二名~
奶牛喜欢吃苹果。约翰有两棵苹果树,有 N 只苹果会从树上陆续落下。如果掉苹果的时候,贝西在那棵树下,她就能接住苹果。贝西一开始在第一棵树下。在苹果掉落之前,她有足够的时间来回走动,但她很懒,最多只愿意移动 K 次。请计算一下她最多可以接住几只苹果。
• 第一行:两个整数 N 和 K,1 ≤ N ≤ 1000; 1 ≤ K ≤ 30
• 第 i + 1 行有一个整数 Ti,表示第 i 只苹果从哪棵树上掉落,1 表示从第一棵树,2 表示从第二棵树
单个整数:表示能接住的最大苹果数量
7 2
2
1
1
2
2
1
1
6
线性暴力dp
#include
using namespace std ;
const int N=1e3+5;
int a[N],f[N][35][3];
int n,m,k,ans=0,i,j;
int main()
{
// freopen("bcatch.in","r",stdin);
// freopen("bcatch.out","w",stdout);
for(scanf("%d%d",&n,&k),i=0;++i<=n;)scanf("%d",&a[i]);
if(a[1]==1)f[1][0][1]=1,f[1][1][1]=1,f[1][0][2]=0;
if(a[1]==2)f[1][0][2]=1,f[1][1][2]=1,f[1][0][1]=0;
for(i=0;++i<=n;)
{
for(j=-1;++j<=k;)
{
if(a[i]==1)
{
f[i][j][2]=max(f[i-1][j][2],f[i][j][2]);
f[i][j][1]=max(f[i-1][j][1]+1,f[i][j][1]);
if(j!=k)f[i][j][1]=max(f[i][j][1],f[i-1][j+1][2]+1);
}
else
{
f[i][j][1]=max(f[i-1][j][1],f[i][j][1]);
f[i][j][2]=max(f[i-1][j][2]+1,f[i][j][2]);
if(j!=k)f[i][j][2]=max(f[i][j][2],f[i-1][j+1][1]+1);
}
}
}
for(i=-1;++i<=k;)ans=max(ans,max(f[n][i][1],f[n][i][2]));
printf("%d",ans);
return 0;
}
农夫顿因开始玩飞盘之后,约翰也打算让奶牛们享受飞盘的乐趣.他要组建一只奶牛飞盘队.
他的N(1≤N≤2000)只奶牛,每只部有一个飞盘水准指数Ri(1≤Ri≤100000).约翰要选出1只或多于1只奶牛来参加他的飞盘队.
约翰比较迷信,他的幸运数字是F,所以他要求队伍的总能力必须是F的倍数。请帮他算一下,符合这个要求的队伍组合有多少?由于这个数字很大,只要输出答案除以10^8 的余数就可以了。
第一行:两个用空格分开的整数:N和F,1 ≤ N ≤ 2000,1 ≤ F ≤ 1000
第二行到N + 1行:第i + 1行有一个整数R i ,表示第i头奶牛的能力,1 ≤ R i ≤ 10^5
4 5
1
2
8
2
3
全盘第二水的题,必须过,注意简单的不正宗状压一下
#include
using namespace std;
const int N=2e3+5;
const int MOD=1e8;
int n,m,i,j,k,len,ans,sum=0;
int a[N],f[N][N];
bool bo[N];
int main()
{
// freopen("fristeam.in","r",stdin);
// freopen("fristeam.out","w",stdout);
for(scanf("%d%d",&n,&m),i=0;++i<=n;)
{
for(scanf("%d",&k),f[i][k%m]=1,j=-1;++j<m;)
{
f[i][j]=(f[i][j]+f[i-1][j])%MOD;
f[i][(j+k)%m]=(f[i][(j+k)%m]+f[i-1][j])%MOD;
}
}
printf("%d",f[n][0]);
return 0;
}
2 3 10
10 15 15
13 11 20
24
思维方面很难,但看透了,不过就是个背包
#include
using namespace std;
const int N=2e6+5;
int f[N],a[102][102];
int n,m,k,i,j,s,d;
int main()
{
// freopen("stock.in","r",stdin);
// freopen("stock.out","w",stdout);
for(scanf("%d%d%d",&n,&d,&m),i=0;++i<=n;)
for(j=0;++j<=d;)
scanf("%d",&a[j][i]);
for(k=0;++k<d;)
{
for(memset(f,0,sizeof(f)),i=0;++i<=n;)
for(j=a[k][i]-1;++j<=m;)
f[j]=max(f[j],f[j-a[k][i]]+a[k+1][i]-a[k][i]);
m+=f[m];
}
printf("%d",m);
return 0;
}
给定一个1*N(2<=N<=248) 的地图,在里面玩2048,每次可以合并相邻两个(数值范围1-40),问最大能合出多少。注意合并后的数值并非加倍而是+1,例如2与2合并后的数值为3。
第一行,一个整数N
接下来N行,每行一个整数,表示第i个数字
所求的答案
4
1
1
1
2
3
应该是最基础的了吧,跟石子合并一样难的区间dp
#include
using namespace std;
const int N=248+5;
int n,m,i,j,k,l,ans;
int f[N][N];
int main()
{
freopen("248.in","r",stdin);
freopen("248.out","w",stdout);
for(scanf("%d",&n),i=0;++i<=n;)scanf("%d",&f[i][i]);
for(i=0;++i<n;)
{
for(j=0;++j<=n;)
{
l=j+i;
if(l>n)break;
for(k=j-1;++k<l;)
{
if(!(f[j][k]^f[k+1][l]))
{
f[j][l]=max(f[j][l],f[j][k]+1);
ans=max(ans,f[j][l]);
}
}
}
}
printf("%d",ans);
return 0;
}
第一行,一个整数N
接下来N行,每行一个整数,表示第i个数字
所求的答案
4
1
1
1
2
3
这道题跟上一题,题意一样,但数据打了不少?怎么dp》》》
这个东西考试时候没有做出来,但没有想到竟然会短
嗯,仅仅是短:
https://www.cnblogs.com/Achensy/p/10804621.html
分享一位比较厉害的人写的题解
没有颜色才是纯