子集和数问题

由于本实验是为了验证数据集影响,因此没有采用一次增加两个的限界函数。此代码左支限界是 w+wi> target,右支限界是w+rest>=target. 并且由于实验网站要求在没有正确解的情况下输出近似解,因此每次触底或者左支终止之后还进行了记录。最后因为进行了排序,而数据集给出的答案中并没有进行排序,因此使用了一个结构体对开始的位置进行记录。

#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include <windows.h>
#define N 6
#define MAX_ANS 1000
using namespace std;
struct node
{
int sum;
int loc;
};
int time=0;
int ans=0;
int nearest = 0;
int use[MAX_ANS][N+1];
void quick(vector<node>& a, int l, int r)
{
if(l < r)
{
int i=l, j=r, key=a[l].sum;
while(i<j)
{
while(i<j && a[j].sum>=key)
{
j--;
}
while(i<j && a[i].sum<=key)
{
i++;
}
swap(a[i], a[j]);
}
swap(a[i], a[l]);
quick(a, l, i-1);
quick(a, i+1, r);
}
}
int solve(vector<node> a, int target, int now, int sum, int r)
{
if(now<0 || now>N-1)
{
return 0;
}
if(use[ans][now] == 2) //这个节点还没有被访问过
{
int temp_sum = sum+a[now].sum;
if(now == N-1) //触底
{
if(temp_sum == target)
{
use[ans][now] = 1;
for(int i=0; i<N; i++)
{
use[ans+1][i] = use[ans][i];
}
ans++;
time++;

}
else if(temp_sum < target && (nearest > temp_sum || nearest == 0))
{
nearest = temp_sum;
use[ans][now] = 1;
for(int i=0; i<N; i++)
{
use[MAX_ANS-1][i] = use[ans][i];
}

}
else//直接转向右支触底
{
if(nearest > sum)
{
use[ans][now] = 0;
nearest = sum;
for(int i=0; i<N; i++)
{
use[MAX_ANS-1][i] = use[ans][i];
}
}
}
use[ans][now] = 2;
return solve(a, target, now-1, sum, r);
}

//没触底的正常处理流程
if(temp_sum == target) //等于就记录(time++)并且跳过这个节点
{
use[ans][now] = 1;
for(int i=0; i<N; i++)
{
use[ans+1][i] = use[ans][i];
}
ans++;
time++;
return solve(a, target, now, sum+a[now].sum, r-a[now].sum);
}
else if(temp_sum < target)
{
use[ans][now] = 1;
return solve(a, target, now+1, sum+a[now].sum, r-a[now].sum);
}
else
{
use[ans][now] = 2;
if(now < nearest)
{
nearest = now;
for(int i=0; i<N; i++)
{
use[MAX_ANS-1][i] = use[ans][i];
}
}
return solve(a, target, now-1, sum, r);
}

}
else//回溯
{
if(use[ans][now] == 1 && r+now>nearest) //该节点已经访问左支
{
use[ans][now] = 0;
return solve(a, target, now+1, sum-a[now].sum, r+a[now].sum);
}
else
{
use[ans][now] = 2;
return solve(a, target, now-1, sum, r);
}
}
return 0;
}
int main()
{
fstream input_stream;
input_stream.open("p08_w.txt", ios::in);
fstream target_stream;
target_stream.open("p08_c.txt", ios::in);
fstream ans_stream;
ans_stream.open("p02_s.txt", ios::in);
int target ;
vector<node> sum;
vector<string> std_ans;
node temp_flag;
string temp_string;
int temp_loc = 0;
while(!input_stream.eof())
{
input_stream>>temp_flag.sum;
temp_flag.loc = temp_loc++;
sum.push_back(temp_flag);
}
while(!target_stream.eof())
{
target_stream>>target;
}
while(!ans_stream.eof())
{
ans_stream>>temp_string;
std_ans.push_back(temp_string);
}
input_stream.close();
target_stream.close();
ans_stream.close();

for(int i=0; i<MAX_ANS; i++)
{
for(int k=0; k<N; k++)
{
use[i][k] = 2;
}
}
int len = sum.size();
quick(sum, 0, len-1);
int all = 0;
for(int i=0; i<len; i++)
{
all+=sum[i].sum;
}
LARGE_INTEGER start_time, end_time, tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&start_time);
solve(sum, target, 0, 0, all);
QueryPerformanceCounter(&end_time);
double duration_time = (double)(end_time.QuadPart-start_time.QuadPart) / tc.QuadPart;
cout<<duration_time<<endl;
for(int i=0; i<time; i++)
{
for(int k=0; k<N; k++)
{
if(use[i][k] == 2)
{
cout<<0<<" ";
}
else
{
cout<<use[i][k]<<" ";
}
}
cout<<endl;
}
cout<<endl;

int *print_ans = new int[len];
for(int i=0; i<time; i++)
{
for(int k=0; k<N; k++)
{
temp_loc = sum[k].loc;
int temp = use[i][k];
if(temp == 2)
{
print_ans[temp_loc] = 0;
}
else
{
print_ans[temp_loc] = temp;
}
}
for(int k=0; k<N; k++)
{
cout<<print_ans[k]<<" ";
}
cout<<endl;
}
if(time == 0)
{
for(int i=0; i<N; i++)
{
int temp = use[MAX_ANS-1][i];
if(temp == 2)
{
print_ans[sum[i].loc] = 0;
}
else
{
print_ans[sum[i].loc] = temp;
}
}
for(int i=0; i<N; i++)
{
cout<<print_ans[i]<<" ";
}
}
delete [] print_ans;
return 0;
}

01背包问题

#include<iostream>
#include <windows.h>
#include <iomanip>
#include <time.h>
using namespace std;
#include <algorithm>

int w[16] = {0,70,73,77,80,82,87,90,94,98,106,1110,113,115,118,120}; //商品的重量
int v[16] = {0,135,139,149,150,156,163,173,184,192,201,210,214,221,229,240}; //商品的价值
int bagV = 750; //背包大小
int dp[16][751] = { { 0 } }; //动态规划表
int item[7]; //最优解情况

void findMax() { //动态规划
for (int i = 1; i <= 15; i++) {
for (int j = 1; j <= bagV; j++) {
if (j < w[i])
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
}
}
}

void findWhat(int i, int j) { //最优解情况
if (i >= 0) {
if (dp[i][j] == dp[i - 1][j]) {
item[i] = 0;
findWhat(i - 1, j);
}
else if (j - w[i] >= 0 && dp[i][j] == dp[i - 1][j - w[i]] + v[i]) {
item[i] = 1;
findWhat(i - 1, j - w[i]);
}
}
}

void print() {
for (int i = 0; i < 16; i++) //最优解输出
cout << item[i] << ' ';
cout << endl;
}

int main()
{
LARGE_INTEGER start_time, end_time, tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&start_time);
findMax();
findWhat(15, 750);
QueryPerformanceCounter(&end_time);
double duration_time = (double)(end_time.QuadPart-start_time.QuadPart) / tc.QuadPart;
cout<<duration_time<<endl;
print();
return 0;
}

多源最短路问题

#include<iostream>
#include<fstream>
#include<windows.h>
#define MAX_SUM 1000
#define MAX 0x3f3f3f3f
#define N 6
using namespace std;

int m[MAX_SUM][MAX_SUM];
void solve()
{
for(int k=0; k<N; k++)
{
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
m[i][j] = min(m[i][j], m[i][k]+m[k][j]);
}
}
}
}

int main()
{
for(int i=0; i<MAX_SUM; i++)
{
for(int k=0; k<MAX_SUM; k++)
{
m[i][k] = MAX;
}
}
fstream input_stream;
input_stream.open("p0.txt", ios::in);
while(!input_stream.eof())
{
int from, to;
double sum;
input_stream>>from;
input_stream>>to;
input_stream>>sum;
m[from][to] = sum;
}
input_stream.close();
LARGE_INTEGER start_time, end_time, tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&start_time);
solve();
QueryPerformanceCounter(&end_time);
double duration_time = (double)(end_time.QuadPart-start_time.QuadPart) / tc.QuadPart;
cout<<duration_time<<endl;
return 0;
}