P1796 汤姆斯的天堂梦
#include<cstdio>
#include<climits>
using namespace std;
int f[200][200]={0};
int main()
{
int n,a;
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d",&a);
for(int j=1;j<=a;++j)
{
f[i][j]=INT_MAX-1000;//初始化,防止溢出
int b,c;
scanf("%d",&b);
while(b!=0)
{
scanf("%d",&c);
f[i][j]=f[i-1][b]+c<f[i][j]?f[i-1][b]+c:f[i][j];//DP
scanf("%d",&b);
}
}
}
int min=INT_MAX;
for(int i=1;i<=a;++i)//在最后一行中找最小值
min=f[n][i]<min?f[n][i]:min;
printf("%d",min);
return 0;
}
P1806 跑步
#include<iostream>
using namespace std;
int n;
//存放答案
//long long 防止超出int
long long ans[501][501];
//最终答案
long long lans = 0;
int main()
{
cin >> n;
//初始条件,跑i圈,最后一次跑i圈,只有一个方案
for (int i = 1; i <= n; i++)
{
ans[i][i] = 1;
}
//状态转移方程
//外层循环为圈数
for (int i = 2; i <= n; i++)
{
//中层循环为最后一次跑的次数
for (int j = 1; j < i; j++)
{
//内层循环为上次跑的次数
for (int k = 1; k < j; k++)
{
ans[i][j] += ans[i - j][k];
}
}
}
//答案时ans[n]所有数都加起来
for (int i = 1; i < n; i++)
{
lans += ans[n][i];
}
cout << lans << endl;
return 0;
}
P8742 [蓝桥杯 2021 省 AB] 砝码称重
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 105;
ll n;
ll a[N],m,ans;
bool f[N][100005];
int main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for(ll i = 1;i <= n; i++) {
cin >> a[i];
m += a[i];
}
for(ll i = 1;i <= n; i++){
for(ll j = m;j >= 1; j--){
if(a[i] == j) f[i][j] = 1;
else f[i][j] = f[i - 1][j] | f[i - 1][abs(j - a[i])] | f[i - 1][j + a[i]];
}
}
for(ll i = 1;i <= m; i++){
if(f[n][i]) ans++;
}
cout << ans << endl;
return 0;
}
P1959 遗址
#include<iostream>
using namespace std;
//n、坐标x、坐标y、答案
int n, cx[3001], cy[3001], ans = 0;
//存放哪些坐标有点
bool map[5001][5001];
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> cx[i] >> cy[i];
map[cx[i]][cy[i]] = true;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
//避免重复选点
if (i == j)
{
continue;
}
//(x1, y1)第一种情况的第一个坐标
//(x2, y2)第一种情况的第二个坐标
//(x3, y3)第二种情况的第一个坐标
//(x4, y4)第二种情况的第二个坐标
int x1, x2, y1, y2, x3, x4, y3, y4;
//数学方法推算
x1 = (cy[j] - cy[i]) + cx[i];
x2 = (cy[j] - cy[i]) + cx[j];
y1 = (cx[i] - cx[j]) + cy[i];
y2 = (cx[i] - cx[j]) + cy[j];
x3 = (-cy[j] + cy[i]) + cx[i];
x4 = (-cy[j] + cy[i]) + cx[j];
y3 = (-cx[i] + cx[j]) + cy[i];
y4 = (-cx[i] + cx[j]) + cy[j];
//保证坐标在范围内,并且坐标上有点
//第一种情况
if (x1 >= 0 && x1 <= 5000 && x2 >= 0 && x2 <= 5000 && y1 >= 0 && y1 <= 5000 && y2 >= 0 && y2 <= 5000 && map[x1][y1] && map[x2][y2])
{
ans = max(ans, (cy[j] - cy[i]) * (cy[j] - cy[i]) + (cx[i] - cx[j]) * (cx[i] - cx[j]));
}
//第二种情况
else if (x3 >= 0 && x3 <= 5000 && x4 >= 0 && x4 <= 5000 && y3 >= 0 && y3 <= 5000 && y4 >= 0 && y4 <= 5000 && map[x3][y3] && map[x4][y4])
{
ans = max(ans, (cy[j] - cy[i]) * (cy[j] - cy[i]) + (cx[i] - cx[j]) * (cx[i] - cx[j]));
}
}
}
cout << ans << endl;
return 0;
}
P8794 [蓝桥杯 2022 国 A] 环境治理
#include<iostream>
#include<cstring>
using namespace std;
//n、Q、原始的灰尘度、最低灰尘度、当前的指标p、答案、临时存放Floyd答案的数组
int n, q, dis[101][101], l[101][101], p, ans = -1, tempdis[101][101];
//Floyd算法
void floyd()
{
for (int k = 1; k <= n; k++)
{
for (int i = 1; i <= n; i++)
{
for (int j =1; j <= n; j++)
{
tempdis[i][j] = min(tempdis[i][j], tempdis[i][k] + tempdis[k][j]);
}
}
}
}
//求解指标P的值
int getp()
{
int sum = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
sum += tempdis[i][j];
}
}
return sum;
}
//设置当前的天数(把当前天数已经改善的道路都更新一遍)
void setd(int d)
{
//将原始灰尘度复制到临时数组
memcpy(tempdis, dis, sizeof(dis));
//更新灰尘度
for (int i = 1; i <= d; i++)
{
for (int j = 1; j <= n; j++)
{
tempdis[j][i] = max(l[j][i], tempdis[j][i] - 1);
tempdis[i][j] = max(l[i][j], tempdis[i][j] - 1);
}
}
}
int main()
{
cin >> n >> q;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> dis[i][j];
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> l[i][j];
}
}
//二分
int l = 0, r = n;
while (l <= r)
{
int mid = (l + r ) / 2;
//设置天数
setd(mid);
//计算最短路径
floyd();
//判断p是否小于等于q
if (getp() <= q)
{
r = mid - 1;
//更新答案
ans = mid;
}
else
{
l = mid + 1;
}
}
//没有答案时是默认-1,有答案就是最新的(也就是最小的)天数
cout << ans << endl;
return 0;
}