日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

1.14 日志(递推ybtoj)

發布時間:2023/12/3 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1.14 日志(递推ybtoj) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

明天要模擬,n年未碰電腦,先不學新的了。。。。

1.錯排問題

dp最棒了

code:
#include
#include
#include
#include
#include
using namespace std;
const int M=INT_MAX;
long long f[25][25]={ };//f[i][j]表示有i個數,其中j個數可以隨便填
int jc[22];
void solve(){
jc[1]=1;
for(int i=2;i<=20;i++){
jc[i]=jc[i-1] * i;
}

}
long long dp(int num,int a){
if(f[num][a]!=0) return f[num][a];
if(num==a) return jc[num];//都自由則轉化為階乘問題
long long res=0;
if(a!=0){
res += a * dp(num-1,a);
}//討論不可自由填的那一位填什么
if(num>a+1){
res += (num-1-a) * dp(num-1,a+1);
}
f[num][a]=res;
return res;
}
int main(){
f[0][0]=1;
f[1][0]=0;
solve();//我這行一開始忘打了,結果調了半天。。。
int n;
scanf("%d",&n);
long long ans=dp(n,0);
printf("%lld",ans);
return 0;
}

2.奇怪的漢諾塔


與3塔的轉換與取最小值是我沒想到的。。。
#include
#include
#include
#include
#include
using namespace std;
const int M=INT_MAX;
int main(){
int f[15] = { };
int k[15] = { };
for(int i=1;i<=12;i++){
k[i]=M;
}
f[1]=1;
f[2]=3;
k[1]=1;
for(int i=3;i<=12;i++){
f[i] = 2 * f[i-1] + 1;
}
for(int i=2;i<=12;i++){
for(int j=1;j<=i;j++){
k[i] = min(k[i],2*k[j]+f[i-j]);
}
}
for(int i=1;i<=12;i++){
printf("%d\n",k[i]);
}
return 0;
}

數的劃分


一遍AC針不戳(dp太香了)

#include
#include
#include
#include
#include
using namespace std;
const int M = INT_MAX;
int f[202][202][8] = {};
long long dp(int min, int left, int num) {
if (f[min][left][num] != 0)
return f[min][left][num];
if (num == 1)
return 1;
int res = 0;
for (int i = min; i <= left / num; i++) {
res += dp(i, left - i, num - 1);
}
return f[min][left][num] = res;
}
int main() {
int a, b;
scanf("%d%d", &a, &b);
printf("%lld", dp(1, a, b));
return 0;
}

4.傳球游戲


一開始一直在討論奇偶性和轉圈上糾結。。。
#include
#include
#include
#include
#include
using namespace std;
const int M = INT_MAX;
int main() {
int m, n;
long long f[50][50];
scanf("%d%d", &n, &m);
f[0][1] = 1;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (j == 1)
f[i][j] = f[i - 1][n] + f[i - 1][2];
else if (j == n)
f[i][j] = f[i - 1][n - 1] + f[i - 1][1];
else
f[i][j] = f[i - 1][j - 1] + f[i - 1][j + 1];
}
}
printf("%lld", f[m][1]);
return 0;
}

平鋪方案


opj原題,直接水掉~~

#include
#include
#include
#include
using namespace std;
int ans[1001], x[300][1000];
int pus(int s1[], int s2[]) {
int i;
memset(ans, 0, sizeof(ans));
int l1 = 500;
while (s1[l1] == 0) l1–;
int l2 = 500;
while (s2[l2] == 0) l2–;
for (i = 0; i <= max(l1, l2); i++) {
ans[i] += s1[i] + s2[i];
if (ans[i] >= 10) {
ans[i] -= 10;
ans[i + 1] += 1;
}
}
int k = i + 5;
while (ans[k] == 0) k–;
return k;
}
void solve() {
for (int i = 0; i <= 300; i++) {
for (int j = 0; j <= 500; j++) {
x[i][j] = 0;
}
}
x[0][0] = 1;
x[1][0] = 1;
for (int i = 2; i <= 252; i++) {
if (i == 23) {
int o = 15;
}
if (i == 20) {
int l = 15;
}
int m = pus(x[i - 2], x[i - 1]);
for (int j = 0; j <= m; j++) {
x[i][j] = ans[j];
}
m = pus(x[i], x[i - 2]);
for (int j = 0; j <= m; j++) {
x[i][j] = ans[j];
}
}
}
int main() {
solve();
int p;
while (scanf("%d", &p) != EOF) {
int z = 500;
while (x[p][z] == 0) z–;
for (int i = z; i >= 0; i–) {
printf("%d", x[p][i]);
}
printf("\n");
}
return 0;
}

總結

以上是生活随笔為你收集整理的1.14 日志(递推ybtoj)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。