1354 選數字
基準時間限制:1 秒 空間限制:131072 kb 分值: 80
難度:5級演算法題
當給定乙個序列a[0],a[1],a[2],...,a[n-1] 和乙個整數k時,我們想找出,有多少子串行滿足這麼乙個條件:把當前子串行裡面的所有元素乘起來恰好等於k。
樣例解釋:
對於第乙個資料,我們可以選擇[3]或者[1(第乙個1), 3]或者[1(第二個1), 3]或者[1,1,3]。所以答案是4。
input
多組測試資料。在輸入檔案的第一行有乙個整數t(0output接下來的2*t行,會給出每一組資料
每一組資料佔兩行,第一行包含兩個整數n, k(1<=n<=1000,2<=k<=100000000)他們的含意已經在上面提到。
第二行包含a[0],a[1],a[2],...,a[n-1] (1<= a[i]<=k) 以乙個空格分開。
所有輸入均為整數。
對於每乙個資料,將答案對1000000007取餘之後輸出即可。input示例
2output示例3 31 1 3
3 62 3 6
4解題報告(by system message)2
類似於揹包的dp,以乘積為狀態。先把等選數字裡面不是k約數的去掉。然後找出k的約數,進行離散化。然後dp[i][j]表示前i個數字乘積為j的狀態。dp[i+1][j*a[i+1]]]+=dp[i][j].
dp[i+1][j]+=dp[i][j];
總的複雜度是o(n*d(k)*log(d(k)))
d(k)表示k的因子數目。多乙個log是因為離散化了,對應下標的時候要二分查詢。
如果按照一般的揹包肯定會t的。。1e3個數字,每個數字1e8個揹包大小。。所以優化一下,去掉沒用的狀態,只留下是k的因子的狀態就好了。。用map做很好,因為map裡存的都是因子,根據這個轉移,網上還有一種**是先離散化。。。
#include #include #include #include #include using namespace std;
const int maxn = 1e3 + 5;
const int mod = 1000000007;
int a[maxn];
int main()
ans[a[i]] = (ans[a[i]] + 1)%mod;
}printf("%d\n", ans[k]);
}return 0;
}
先離散化,但思路都是一樣的
#include #include #include #include #include using namespace std;
const int mod = 1e9 + 7;
const int maxn = 1010;
const int maxm = 100001;
int a[maxn];
int b[maxn];
int dp[maxm];
maptemp;
int main(void)
// 求k約數
int cnt = 0;
for (i = 1; i * i < k; i++)
b[cnt++] = i;
b[cnt++] = k / i;
}if (i * i == k)
sort(b, b + cnt);
for (i = 0; i < cnt; i++)
for (i = 0; i < n; i++)
int tmp = temp[a[i]];
for (int j = temp[k]; j >= 0; j--)
}dp[tmp] = (dp[tmp] + 1) % mod;
}printf("%d\n", dp[cnt - 1]);
}return 0;
}
動態規劃 0 1揹包選不選
1.給你n件物品,給你乙個包重量為m 問你正好裝 積為m?有多少種選擇 我這件物品要麼就是裝進來,要麼就是不裝進來,2 n種選擇 找到遞迴退出條件 揹包容量為0,則有唯一一種裝法 0件物品則只有0件裝法 poj 2755.cpp 定義控制台應用程式的入口點。include stdafx.h incl...
CODE VS 1025 選菜 揹包
在小松宿舍樓下的不遠處,有pk大學最不錯的乙個食堂 the farmer s canteen nm食堂 由於該食堂的菜都很不錯,也公道,所以很多人都喜歡來這邊吃飯。the farmer s canteen的點菜方式如同在超市自選商品一樣,人們從乙個指定的路口進去,再從乙個指定的路口出來並付款。由於來...
類似0 1揹包的dfs 選與不選
題目大意 思路 每個傳送陣可以選擇傳送或者不傳送。從n 1開始考慮。從終點最遠的傳送陣開始列舉 include using namespace std define ll long long struct node node 16 int cmp node a,node b ll t ll l,ll...