


注意第一个遍历的边界条件,这里弄错了,应该是小于,不应该是小于等于
// 计算所有的合法状态
// 注意,这里应该是小于,而不是小于等于,最后一个移位的情况完全没有满足
// 写错了: for (int i = 0; i <= 1<< n; ++i) {
for (int i = 0; i < 1<< n; ++i) {
if (check(i)){
state.push_back(i);
cnt[i] = count(i);
}
}
// 计算所有的合法转移的方程
for (int i = 0; i < state.size(); ++i) {
for (int j = 0; j < state.size(); ++j) {
int a = state[i],b = state[j];
if((a & b) == 0 && check(a | b) ){
head[i].push_back(j);
}
}
}
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 12;// 这里是为了简便运算
const int M = 1<< 10; // 这里是定义了最多的状态数,相当于是2的十次方
const int k = 110;
int n,m; // n保存棋盘的大小,m是国王的数量
vector<int> state;// 保存所有合法的状态
vector<int> head[M]; // 最多有M种状态,这里是每一个状态的合法转移状态情况
int cnt[M]; // 每一种状态的国王的个数,也就是1的个数
LL f[N][k][M];
bool check(int x){
// 检查某一个状态是否合法
for (int i = 0; i < n; ++i) {
if ((x >> i & 1) && (x >> (i+ 1) & 1)){
return false;
}
}
return true;
}
int count(int x){
int r = 0;
for (int i = 0; i < n; ++i) {
if(x >> i & 1 ) r++;
}
return r;
}
int main(){
cin>>n>>m;
// 计算所有的合法状态
// 因为通过+1进行遍历,所以要从零开始
for (int i = 0; i < 1<< n; ++i) {
if (check(i)){
state.push_back(i);
cnt[i] = count(i);
}
}
// 计算所有的合法转移的方程
for (int i = 0; i < state.size(); ++i) {
for (int j = 0; j < state.size(); ++j) {
int a = state[i],b = state[j];
if((a & b) == 0 && check(a | b) ){
head[i].push_back(j);
}
}
}
// 实现状态转移的计算,这里是以下标作为直接索引的。
f[0][0][0] = 1;
for (int i = 1; i <= (n + 1) ; ++i) {
for (int j = 0; j <= m; ++j) {
for (int a = 0; a < state.size(); ++a) {
for (auto b:head[a]) {
int c = cnt[state[a]];
if (c <= j){
f[i][j][a] += f[i -1][j - c][b];
}
}
}
}
}
// 正常情况下,应该遍历所有的子状态,但是这里相当于是下一行完全没摆放的状态
cout<<f[n + 1][m][0]<<endl;
}

#include
#include
#include
#include
using namespace std;
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end(),[](auto a,auto b){
return a < b;
});
vector<vector<int>> res;
set<vector<int>> reIdx;
for (int i = 0; i < nums.size(); ++i) {
int tar = 0 - nums[i];
int a = 0,b = nums.size() - 1;
while(a < b){
if (a == i) a ++ ;
else if (b == i) b -- ;
else{
if (nums[a] + nums[b] > tar) b--;
else if (nums[a] + nums[b] < tar) a ++;
else{
if(i < a)
reIdx.insert({nums[i],nums[a],nums[b]});
else if(i < b)
reIdx.insert({nums[a],nums[i],nums[b]});
else
reIdx.insert({nums[a],nums[b],nums[i]});
b-- ,a++;
}
}
}
}
for (auto temp : reIdx) {
res.push_back({temp[0],temp[1],temp[2]});
}
return res;
}
int main(){
vector<int> s = {-1,0,1,2,-1,-4};
vector<vector<int>> res = threeSum(s);
for (auto & re : res) {
cout<<re[0]<<re[1]<<re[2]<<endl;
}
}

vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end(),[](auto a,auto b){
return a < b;
});
vector<vector<int>> res;
for (int i = 0; i < nums.size(); ++i) {
if(i && nums[i] == nums[i - 1]) continue;
for (int j = i + 1,k = nums.size() - 1; j < k; ++j) {
if(j > i + 1 && nums[j] == nums[j - 1]) continue;
// 这里确实很巧妙,过渡到k不变了,真的蛮厉害的
while(j < k - 1 && nums[i] + nums[j] + nums[k - 1] >= 0) k --;
if(nums[i] + nums[j] + nums[k] == 0)
res.push_back({nums[i], nums[j], nums[k]});
}
}
return res;
}
#include
#include
#include
using namespace std;
int threeSumClosest(vector<int>& n, int target) {
sort(n.begin(),n.end());
int res = 0,minV = INT_MAX;
for (int i = 0; i < n.size(); ++i) {
for (int j = i + 1,k = n.size() - 1; j < n.size(); ++j) {
if (j + 1 < n.size() && n[j + 1] == n[j]) continue;
// for (int l = 0; n[j] + n[k - 1] >= target ; ++l) {
//
// }
if (k - 1 >= 0 && n[k - 1] == n[k]) {
k --;
continue;
}
if (minV > (target - n[i] - n[j] - n[k])){
res = n[i] + n[j] + n[k];
minV = target - res;
}
if( (target - n[i] - n[j] - n[k]) > 0)
k --;
else
j ++;
}
}
return res;
}
int main(){
int n = 1;
vector<int> nums = {1,2,3,4};
int tar = 10;
cout<<threeSumClosest(nums,tar)<<endl;
}

#include
#include
#include
using namespace std;
int threeSumClosest(vector<int>& n, int target) {
sort(n.begin(),n.end());
pair<int ,int > res(INT_MAX,INT_MAX); // 这两个数字表示插值和对应的和
for (int i = 0; i < n.size(); ++i) {
for (int j = i + 1,k = n.size() - 1; j < k; ++j) {
while(k - 1 > j && n[i] + n[j] + n[k - 1] >= target) k --;
int s = n[i] + n[j] + n[k];
res = min(res, make_pair(abs(target- s),s));
if (k - 1 > j){
s = n[i] + n[j] + n[k - 1];
res = min(res, make_pair(target- s,s));
}
}
}
return res.second;
}
int main(){
int n = 1;
vector<int> nums = {1,2,3,4};
int tar = 10;
cout<<threeSumClosest(nums,tar)<<endl;
}