n個機械人,每個機械人會讀入乙個x,並返回ax+b。現在有乙個x,想讓你合理安排機械人順序,使得最終返回得到的x盡可能大,輸出最大值。(1<=n,x,ai,bi<=20)
給的範圍很小才20,那麼就可以考慮到狀壓dp。
dp[i][t]表示第i次迴圈在狀態t的情況下出的最大值。t在二進位制狀態下1的位置表示該位置的機械人已經取過,比如5(101)表示1和3位置的機械人已經使用過。所以第i次迴圈中就列舉狀態t中0的位置j,然後使用該機械人j,那麼使用過機械人j之後狀態就變成了t2=t|(1《然後還可以進行記憶化搜尋,當然啦,其實原理差不多,但是畢竟是記憶化搜尋,少跑好多內容,時間上會節省好多,具體看**。
需要注意的是最大值是20^20次,爆longlong了,這裡使用了__int128以及他的輸出函式。
狀壓dp
#includeusing namespace std;
#define io cin.tie(0);ios::sync_with_stdio(false);
#define ok(x, y) x >= 1 && x <= n && y >= 1 && y <= m
#define debug(x) cout<<#x<<"="<#define mk make_pair
#define ll long long
#define ull unsigned long long
#define lb long double
#define rs p<<1|1
#define ls p<<1
#define eps 1e-6
#define pi acos(-1)
const int maxn = 2e5 + 5;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
const int bas = 2333;
inline ll read()
while(c>='0'&&c<='9')
return f*p;
}void print(__int128 x)
if (x>9) print(x/10);
putchar('0'+x%10);
}__int128 dp[25][1<<20];
int a[25], b[25];
void solve()
while(c>='0'&&c<='9')
return f*p;
}void print(__int128 x)
if (x>9) print(x/10);
putchar('0'+x%10);
}__int128 dp[1<<20];
int a[25], b[25], n;
__int128 dfs(int x)
return dp[x];
}void solve()
int main()
計蒜客 灌溉機械人(狀壓DP)
灌溉機械人 include include using namespace std const int max n 100 const int max m 10 int state max n 1 i行狀態 int dp max n 1 1 max m 1 max m i行狀態為j i 1行狀態為k...
牛客寒假演算法基礎訓練營1 G
這道題的題解講的非常好了已經,對於1 n數的排列子區間 l,r 使得區間中的數滿足連續的條件為 r l max a l r min a l r l,r為下標 既然要使 l,r 為萌區間,那麼就要找到這個區間內的最大值mx與最小值mn,判斷是否滿足條件 若不滿足條件,那麼需要將 mn,mx 缺少的數字...
牛客訓練營1 C(2 0)
題目描述 小a正在玩一款星際探索遊戲,小a需要駕駛著飛船從1號星球出發前往n號星球。其中每個星球有乙個能量指數p。星球i能到達星球j當且僅當pi pj。同時小a的飛船還有乙個耐久度t,初始時為1號點的能量指數,若小a前往星球j,那麼飛船的耐久度會變為t pj 即t異或pj 小a想知道到達n號星球時耐...