1. 买不到的数目
ACWing1205. 买不到的数目
输入样例:
4 7
输出样例:
17
#include<iostream>
using namespace std;
int main()
{
int p,q;
cin >> p >> q;
cout << (p-1)*(q-1)-1 <<endl;
return 0;
}
2.蚂蚁感冒
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 55;
int n, x[N];
int main()
{
cin >>n;
for(int i = 0; i < n; i++) cin >> x[i];
int left = 0, right = 0;//分别表示左边向右走的蚂蚁数量,和右边向左走的蚂蚁数量
for(int i = 1; i < n; i++)
if(abs(x[i]) < abs(x[0]) && x[i] >0) left++;//左边向右走
else if(abs(x[i]) > abs(x[0]) && x[i] <0) right++;
//第一个蚂蚁向右 right > 0 left + right + 1
// right == 0 1
//第一个蚂蚁向左 left > 0 left + right + 1
// left == 0 1
if(x[0] >0 && right == 0|| x[0] < 0 && left == 0) cout << 1<<endl;
else cout << left + right + 1 <<endl;
return 0;
}
3. 饮料换购
#include<iostream>
using namespace std;
const int N = 10010;
int cnt;
int main()
{
int n;
cin >>n;
cnt = n;
while(n >= 3)
{
cnt += (n)/3;
n = n/3 + n%3;
}
cout << cnt;
return 0;
}
4. 摘花生
ACWing1015. 摘花生
思路
状态表示
集合:定义f[i][j]为从(1, 1)到达(i, j)的所有方案
属性:最大值
状态转移
(i, j)从(i-1, j)即上方过来
(i, j)从(i, j-1)即左方过来
空间压缩
f[i][j]只需要用到这一层和上一层的f元素,所以可以压缩成滚动数组。在此之上,还可以直接压缩成一维数组。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 110;
int g[N][N];
int f[N];
int main()
{
int n, r,c;
cin>> n;
while(n--)
{
cin >> r >> c;
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)
scanf("%d", &g[i][j]);
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)
f[j] = max(f[j], f[j-1]) + g[i][j];
cout << f[c] <<endl;
memset(f,0,sizeof f);
}
return 0;
}
5.地宫取宝
ACWing1212. 地宫取宝
X 国王有一个地宫宝库,是 n×m 个格子的矩阵,每个格子放一件宝贝,每个宝贝贴着价值标签。
地宫的入口在左上角,出口在右下角。
小明被带到地宫的入口,国王要求他只能向右或向下行走。
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
当小明走到出口时,如果他手中的宝贝恰好是 k 件,则这些宝贝就可以送给小明。
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这 k 件宝贝。
输入格式
第一行 3 个整数,n,m,k,含义见题目描述。
接下来 n 行,每行有 m 个整数 Ci 用来描述宝库矩阵每个格子的宝贝价值。
输出格式
输出一个整数,表示正好取 k 个宝贝的行动方案数。
该数字可能很大,输出它对 1000000007 取模的结果。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 55, mod = 1000000007;
int n, m, k;
int w[N][N];
int f[N][N][13][14];//f[i][j][c][k]表示:在(i, j)这个点,拿了c个物品,这些物品中价值最大的是k
int main()
{
cin >> n >>m >> k;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
cin >> w[i][j];
w[i][j]++;
}
//两个边界初始化
//在起点(1, 1)处
//如果拿也只能拿a[i][j]这个物品,只有一种方案
//如果不拿,那就是0个物品,也是一个方案数
//由于物品价值已经增加了一个偏移量,现在价值的范围是[1, 13]
//所以价值为0并不代表物品的价值,而是一个边界点
f[1][1][1][w[1][1]] = 1;//选第一个数
f[1][1][0][0] = 1;//不选第一个数
for(int i = 1 ; i <= n; i++)
for(int j = 1; j <= m; j++)
{
if(i == 1 && j == 1) continue;
for(int u = 0; u <= k; u++)
for(int v = 0; v <= 13; v++)
{
//不拿物品
int &val = f[i][j][u][v];
val = (val + f[i-1][j][u][v])%mod;
val = (val + f[i][j-1][u][v])%mod;
//可以拿
if(u > 0 && v == w[i][j])
{
for(int c = 0; c <v; c++)
{
val = (val +f[i-1][j][u-1][c])%mod;
val = (val + f[i][j-1][u-1][c])%mod;
}
}
}
}
//最后把在终点(n, m)处拿c个物品的方案数累加
int res = 0;
for(int i = 0; i <= 13; i ++) res = (res + f[n][m][k][i])%mod;
cout << res <<endl;
return 0;
}
6.波动数列
Acwing 1214. 波动数列
输入样例:
4 10 2 3
输出样例:
2
样例解释
两个满足条件的数列分别是2 4 1 3和7 4 1 -2。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1010,mod = 100000007;
int f[N][N];
int get_mod(int a, int b)//求a%b的正整数
{
return (a%b+ b)%b;
}
int main()
{
int n, s,a,b;
cin >> n >> s >> a >> b;
f[0][0] = 1;
for(int i = 1; i < n; i++)//枚举i-1项
for(int j = 0; j < n; j++)//枚举第i项的n种可能的状态
f[i][j] = (f[i-1][get_mod(j-a*i,n)]+f[i-1][get_mod(j+b*i,n)])%mod;
cout << f[n-1][get_mod(s,n)]<<endl;
return 0;
}