7-1 小北的包
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, w;
cin >> n >> w;
vector<int>ans(w + 1, 0);
for (int i=0;i<n;i++)
{
int t1,t2;
cin >> t1 >> t2;
for (int i1 = w-t1; i1 >= 0; i1--) {
ans[i1 + t1] = max(ans[i1] + t2, ans[i1 + t1]);
}
}
cout << ans[w] << endl;
return 0;
}
背包问题
7-2 铺瓷砖
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<unsigned long long int>ans = {1,1,3};
for (int i = 0; i < n; i++) {
int t;
cin >> t;
for (int i1 = ans.size()-1; i1 <= t; i1++) {
ans.push_back(ans[i1] + ans[i1 - 1] * 2);
}
cout << ans[t] << endl;
}
}
fn可以由fn-1+2*1瓷砖和fn-2+2*1*2+2*2瓷砖不能与fn-1重复
7-3 小源爱写题
#include <bits/stdc++.h>
using namespace std;
unsigned long long ans = 0;
vector<vector<unsigned long long>>mem(510,vector<unsigned long long>(260));
void dfs(int n, int i) {
if (n == 0)ans++;
if (n < 0)return;
if (mem[n][i] != 0) {
ans += mem[n][i];
return;
}
unsigned long long last = ans;
for (int t = i + 1;t<=(n-1)/2;t++) {
dfs(n - t, t);
}
if (i < n) {
ans++;
}
unsigned long long now = ans;
mem[n][i] = now-last;
}
int main() {
int n;
cin >> n;
/*
1 2 3 (n-1)/2
*/
for (int i = 1; i <= (n - 1) / 2; i++) {
dfs(n - i, i);
}
cout << ans << endl;
return 0;
}
记忆化相当于保存动态数组每次调用时自动使用
7-4 自动补全
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;string s1;
cin >> s1;
cin >> n;
string ans;
bool f=false;
for (int i = 0; i < n; i++) {
string temp;
cin >> temp;
if (temp.find(s1) != string::npos) {
if (f) {
ans = ans < temp ? ans : temp;
}
else {
ans = temp;
f = true;
}
}
}
if (ans != "")cout << ans << endl;
else cout << s1 << endl;
return 0;
}
find找符合条件的然后保存
7-5 数组
#include <bits/stdc++.h>
using namespace std;
int main() {
int n,m;
cin >> n >> m;
vector<int>shu(n,0);
vector<pair<int, int>>cao(m);
for (int i = 0; i < n; i++) {
cin >> shu[i];
}
for (int i = 0; i < m; i++) {
cin >> cao[i].first >> cao[i].second;
}
vector<int>ans; int cha = 0;
for (int i = 0; i < n; i++) {
int max = shu[i];
for (int i1 = 0; i1 < n; i1++) {
if (i == i1)continue;
int min = shu[i1];
vector<int>tempxu;
for (int i2 = 0; i2 < m; i2++) {
if (i1+1 >= cao[i2].first) {
if (i1+1 <= cao[i2].second) {
if((i+1>cao[i2].second)||(i+1<cao[i2].first))
tempxu.push_back(i2);
}
}
}
int mt = max - min + tempxu.size();
if (cha < mt) {
cha = mt;
ans = tempxu;
}
}
}
cout << cha << endl;
cout << ans.size() << endl;
for (int i = 0; i < ans.size(); i++) {
cout << ans[i] + 1 << ' ';
}
return 0;
}
在某一区域内减一,如果最大值和最小值都在或都不在没有影响
如果仅最小值再结果会变大暴力即可
7-6 最小生成树
#include <bits/stdc++.h>
using namespace std;
struct san {
int x=0, y=0, z=0;
};
bool cmp(san s1,san s2) {
return s1.z < s2.z;
}
class mycmp {
public:
bool operator()(san s1,san s2) {
return s1.z < s2.z;
}
};
int gengxin(vector<int>&tong){
vector<int>ans(tong.size(),0);
int count=0;
for(int i=1;i<tong.size();i++){
int le=i;
while (tong[le]!=le)
{
le = tong[le];
}
tong[i]=le;
ans[le]=1;
}
for(int i=1;i<tong.size();i++){
if(ans[i])count++;
}
return count;
}
int findtong(vector<int>&tong,int i){
while (tong[i]!=i)
{
i = tong[i];
}
return i;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
int m;
cin >> m;
int ans=0;
vector<san>bian(m);
vector<int>tong(n+1);
for (int i = 0; i < n+1; i++) {
tong[i] = i;
}
for (int i = 0; i < m; i++) {
cin>>bian[i].x>>bian[i].y>>bian[i].z;
}
sort(bian.begin(), bian.end(), cmp);
for (int i = 0; i < m; ) {
auto it = upper_bound(bian.begin(), bian.end(),bian[i],mycmp());
auto it1 = lower_bound(bian.begin(), bian.end(),bian[i],mycmp());
vector<san>temp(it1, it);
i += temp.size();
//cout<<i<<endl;
vector<int>pan1(temp.size()),pan2(temp.size());
int pan1size=0;
int last=gengxin(tong);
for (int i1 = 0; i1 < temp.size(); i1++) {
//cout<<temp[i1].x<<" "<<temp[i1].y<<" "<<temp[i1].z<<endl;
int le = findtong(tong,temp[i1].x);
int ri = findtong(tong,temp[i1].y);
if (le != ri){
pan1[pan1size]=le;
pan2[pan1size]=ri;
pan1size++;
}
}
//cout<<pan1size<<' '<<pan1.size()<<endl;
for (int i1 = 0; i1 < pan1size; i1++) {
int le =findtong(tong,pan1[i1]);
int ri =findtong(tong,pan2[i1]);
if(le<ri)swap(le,ri);
tong[ri] = le;
}
int now=gengxin(tong);
ans+=pan1size+now-last;
if(now==1)break;
}
cout << ans << endl;
return 0;
}
很遗憾,考试的时候有和题解很相似的想法,不过由于没有真正的答案,自己不断修改,但是始终运行超时,发现连接通路的时候没考虑大小,结果导致死循环而超时
P1135 奇怪的电梯
#include <bits/stdc++.h>
using namespace std;
struct dui{
int lu;
int i;
};
bool hefa(int i,int n){
if(i>=0){
if(i<=n)
return true;
}
return false;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,a,b;
cin>>n>>a>>b;
if(a==b){
cout<<0<<endl;
return 0;
}
vector<int>cao(n+1);
for(int i=1;i<=n;i++){
cin>>cao[i];
}
queue<dui>bu;
dui temp;
temp.lu=a;
temp.i=0;
bu.push(temp);
bool find=false;
vector<int>ans(n+1,0);
while(!bu.empty()){
temp=bu.front();
bu.pop();
if(ans[temp.lu])continue;
ans[temp.lu]=1;
dui next;
next.lu=cao[temp.lu]+temp.lu;
//cout<<cao[temp.lu]<<" "<<temp.lu<<endl;
if(next.lu==b){
find=true;
cout<<temp.i+1<<endl;
break;
}
if(hefa(next.lu,n)){
next.i=temp.i+1;
bu.push(next);
}
//cout<<next.lu<<" "<<next.i<<endl;
next.lu=-cao[temp.lu]+temp.lu;
if(next.lu==b){
find=true;
cout<<temp.i+1<<endl;
break;
}
if(hefa(next.lu,n)){
next.i=temp.i+1;
bu.push(next);
}
//cout<<next.lu<<" "<<next.i<<endl;
}
if(!find)cout<< -1<<endl;
return 0;
}
没考虑a与b相等情况
P1443 马的遍历
#include <bits/stdc++.h>
using namespace std;
const int dx[8]={-1,-2,-2,-1,1,2,2,1};
const int dy[8]={2,1,-1,-2,2,1,-1,-2};
struct dui{
int x,y;
int i;
};
bool hefa(int i,int n){
if(i>0){
if(i<=n)
return true;
}
return false;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m,x,y;
cin>>n>>m;
vector<vector<int>>ans(n+1,vector<int>(m+1,-1));
queue<dui>bu;
dui temp;
cin>>temp.x>>temp.y;
temp.i=0;
bu.push(temp);
while(bu.size()){
dui next=bu.front();
bu.pop();
//cout<<next.x<<next.y<<next.i<<endl;;
if(hefa(next.x,n)){
if(hefa(next.y,m)){
if(ans[next.x][next.y]==-1){
ans[next.x][next.y]=next.i;
}else{
continue;
}
}
}
for(int i=0;i<8;i++){
if(hefa(next.x+dx[i],n)){
if(hefa(next.y+dy[i],m)){
temp.x=next.x+dx[i];
temp.y=next.y+dy[i];
temp.i=next.i+1;
//cout<<temp.x<<temp.y<<temp.i<<endl;;
bu.push(temp);
}
}
}/**/
}
for(int i=1;i<=n;i++){
for(int i1=1;i1<=m;i1++){
cout<<ans[i][i1]<<" ";
}
cout<<endl;
}
return 0;
}
简单bfs 遍历即可
P3958 [NOIP2017 提高组] 奶酪
#include <bits/stdc++.h>
using namespace std;
struct zuo{
int x,y,z;
};
bool keda(int r,zuo x,zuo y){
return (sqrt(pow(x.x-y.x,2)+pow(x.y-y.y,2)+pow(x.z-y.z,2))<=2*r);
}
bool hefa(int i,int n){
if(i>0){
if(i<=n)
return true;
}
return false;
}
bool nailao(){
int n,h,r;
cin>>n>>h>>r;
vector<int>ans(n,0);
vector<zuo>cun(n);
queue<zuo>mem;
for(int i1=0;i1<n;i1++){
cin>>cun[i1].x>>cun[i1].y>>cun[i1].z;
if(cun[i1].z<=r){
ans[i1]=1;
mem.push(cun[i1]);
}
}
while(mem.size()){
zuo temp=mem.front();
mem.pop();
//<<temp.x<<temp.y<<temp.z<<endl;
if(temp.z+r>=h)return true;
for(int i=0;i<n;i++){
if(ans[i]==0){
if(keda(r,temp,cun[i])){
//cout<<temp.x<<temp.y<<temp.z<<" ";
//cout<<cun[i].x<<cun[i].y<<cun[i].z<<endl;
//cout<<(sqrt(pow(temp.x-cun[i].x,2)+pow(temp.y-cun[i].y,2)+pow(temp.z-cun[i].z,2))>=2*r)<<endl;
//cout<<2*r<<endl;
ans[i]=1;
mem.push(cun[i]);
}
}
}
}
return false;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
for(int i1=0;i1<t;i1++){
if(nailao()){
cout<<"Yes"<<endl;
}else {
cout<<"No"<<endl;
}
}
return 0;
}
遍历时不断重复找可达地方然后放入队列
P1162 填涂颜色
#include <bits/stdc++.h>
using namespace std;
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,-1,1};
struct zuo{
int x,y;
};
bool hefa(int i,int n){
if(i>=0){
if(i<=n)
return true;
}
return false;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
vector<vector<int>>ans(n+2,vector<int>(n+2,2));
for(int i=1;i<=n;i++){
for(int i1=1;i1<=n;i1++){
int temp;
cin>>temp;
if(temp){
ans[i][i1]=1;
}
}
}
std::queue<zuo>bu;
zuo temp;
temp.x=0;
temp.y=0;
bu.push(temp);
while(bu.size()){
zuo next=bu.front();
bu.pop();
if(hefa(next.x,n+1)){
if(hefa(next.y,n+1)){
if(ans[next.x][next.y]==2){
ans[next.x][next.y]=0;
for(int i=0;i<4;i++){
temp.x=next.x+dx[i];
temp.y=next.y+dy[i];
bu.push(temp);
}
}
}
}
}
for(int i=1;i<=n;i++){
for(int i1=1;i1<=n;i1++){
cout<<ans[i][i1]<<" ";
}cout<<endl;
}
return 0;
}
初始化直接设为2;
再加厚一圈
从 0 0开始搜索 只有封闭圈内搜不到;