#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n;
cin>>n;
int f[105][105];
//编号表示结尾在第几个等级
f[0][0]=0;
int k[10050];
k[0]=1;
for(int i=1;i<=n;i++)
{
cin>>k[i];
for(int j=1;j<105;j++)
{
f[i][j]=0x3f3f3f;//表示到i等级的第j个数
}
for(int j=1;j<=k[i];j++)
{
int a;
int b;
cin>>a;
while(a!= 0)
{
cin>>b;
f[i][j]=min(f[i][j],f[i-1][a]+b);
cin>>a;
}
}
}
int sum=0x3f3f3f3f;
for(int i=1;i<=k[n];i++)
{
if(sum>f[n][i])
{
sum=f[n][i];
}
}
cout<<sum;
//f[n][x]:找到最小的
return 0;
}
跑步
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
//f[x][y]:跑了x圈 最后一次跑了y圈的方案数
//f[i][j]+=f[i-j][k]
long long sum=0;
long long f[505]={0};
f[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=n;j>=i;j--)
{
f[j]+=f[j-i]; //选定不同结尾的圈数
}
}
cout<<f[n]-1;
return 0;
}
//按照背包问题的思路:可以放进的物品从1...n 且放进的物品大小单调递增
//f[j]表示最后一圈的圈数:相当于用滚动数组优化
砝码称重
#include<iostream>
using namespace std;
int n;
int w[105];
const int maxn=1e5;
int f[102][maxn];
int main()
{
cin>>n;
int sum=0;
for(int i=1;i<=n;i++)
{
cin>>w[i];
sum+=w[i];
}
//f[i][x]表示是否可行:用1和0表示;i表示是前几个砝码,j表示是重量
//01背包的可行性问题
for(int i=1;i<=n;i++)
{
for(int j=sum;j>=0;j--)
{
if(j==w[i]) f[i][j]=1;
else if(f[i-1][j]) f[i][j]=1;
else if(f[i-1][abs(j-w[i])]==1) f[i][j]=1;
//留意绝对值符号
else if(f[i-1][j+w[i]]==1) f[i][j]=1;
}
}
int ans=0;
//统计结果
for(int i=1;i<=sum;i++)
{
if(f[n][i]==1)
ans++;
}
cout<<ans;
return 0;
}
遗址
点开的比较小->floyd算法求最小路
二分答案判断是否符合条件
#include<iostream>
#include<cmath>
using namespace std;
int n;
int m[5005][5005];
int x[5005];
int y[5005];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x[i]>>y[i];
m[x[i]][y[i]]=1;
}
//判断是否为正方形 : 缩短为枚举/搜索两个点
int ma=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
int x1=x[j]-y[i]+y[j];
int y1=y[j]-x[j]+x[i];
int x2=x[i]-y[i]+y[j];
int y2=y[i]-x[j]+x[i];
if(x1>0&&x1<5000&&x2>0&&x2<5000&&m[x1][y1]==1&&m[x2][y2]==1)//是否符合条件
{
int ans=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
if(ma<ans)//统计最大值
ma=ans;
}
}
}
cout<<ma;
return 0;
}